@deuna/react-native-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +15 -0
  3. package/lib/module/DeunaLogs.js +18 -0
  4. package/lib/module/DeunaLogs.js.map +1 -0
  5. package/lib/module/DeunaSDK.js +207 -0
  6. package/lib/module/DeunaSDK.js.map +1 -0
  7. package/lib/module/components/DeunaWebView.js +37 -0
  8. package/lib/module/components/DeunaWebView.js.map +1 -0
  9. package/lib/module/components/DeunaWidget.js +82 -0
  10. package/lib/module/components/DeunaWidget.js.map +1 -0
  11. package/lib/module/components/NewTabWebView.js +55 -0
  12. package/lib/module/components/NewTabWebView.js.map +1 -0
  13. package/lib/module/components/WebViewLoader.js +25 -0
  14. package/lib/module/components/WebViewLoader.js.map +1 -0
  15. package/lib/module/controllers/BaseWebViewController.js +252 -0
  16. package/lib/module/controllers/BaseWebViewController.js.map +1 -0
  17. package/lib/module/controllers/ElementsWidgetController.js +64 -0
  18. package/lib/module/controllers/ElementsWidgetController.js.map +1 -0
  19. package/lib/module/controllers/OpenInNewTabController.js +34 -0
  20. package/lib/module/controllers/OpenInNewTabController.js.map +1 -0
  21. package/lib/module/controllers/PaymentWidgetController.js +98 -0
  22. package/lib/module/controllers/PaymentWidgetController.js.map +1 -0
  23. package/lib/module/helpers/Completer.js +30 -0
  24. package/lib/module/helpers/Completer.js.map +1 -0
  25. package/lib/module/helpers/getController.js +48 -0
  26. package/lib/module/helpers/getController.js.map +1 -0
  27. package/lib/module/index.js +7 -0
  28. package/lib/module/index.js.map +1 -0
  29. package/lib/module/interfaces/constants.js +8 -0
  30. package/lib/module/interfaces/constants.js.map +1 -0
  31. package/lib/module/interfaces/errors.js +36 -0
  32. package/lib/module/interfaces/errors.js.map +1 -0
  33. package/lib/module/interfaces/events/checkout.js +45 -0
  34. package/lib/module/interfaces/events/checkout.js.map +1 -0
  35. package/lib/module/interfaces/events/elements.js +28 -0
  36. package/lib/module/interfaces/events/elements.js.map +1 -0
  37. package/lib/module/interfaces/index.js +6 -0
  38. package/lib/module/interfaces/index.js.map +1 -0
  39. package/lib/module/interfaces/types.js +13 -0
  40. package/lib/module/interfaces/types.js.map +1 -0
  41. package/lib/module/package.json +1 -0
  42. package/lib/module/types/base.js +24 -0
  43. package/lib/module/types/base.js.map +1 -0
  44. package/lib/module/types/env.js +48 -0
  45. package/lib/module/types/env.js.map +1 -0
  46. package/lib/module/types/helpers/buildElementsLink.js +75 -0
  47. package/lib/module/types/helpers/buildElementsLink.js.map +1 -0
  48. package/lib/module/types/helpers/buildNextActionLink.js +33 -0
  49. package/lib/module/types/helpers/buildNextActionLink.js.map +1 -0
  50. package/lib/module/types/helpers/buildPaymentLink.js +54 -0
  51. package/lib/module/types/helpers/buildPaymentLink.js.map +1 -0
  52. package/lib/module/types/helpers/buildVoucherLink.js +48 -0
  53. package/lib/module/types/helpers/buildVoucherLink.js.map +1 -0
  54. package/lib/module/types/helpers/index.js +13 -0
  55. package/lib/module/types/helpers/index.js.map +1 -0
  56. package/lib/module/types/helpers/urlConfig.js +19 -0
  57. package/lib/module/types/helpers/urlConfig.js.map +1 -0
  58. package/lib/module/types/index.js +7 -0
  59. package/lib/module/types/index.js.map +1 -0
  60. package/lib/module/types/interfaces/callbacks.js +2 -0
  61. package/lib/module/types/interfaces/callbacks.js.map +1 -0
  62. package/lib/module/types/interfaces/customStyle.js +2 -0
  63. package/lib/module/types/interfaces/customStyle.js.map +1 -0
  64. package/lib/module/types/interfaces/index.js +9 -0
  65. package/lib/module/types/interfaces/index.js.map +1 -0
  66. package/lib/module/types/interfaces/initWidgetBase.js +4 -0
  67. package/lib/module/types/interfaces/initWidgetBase.js.map +1 -0
  68. package/lib/module/types/interfaces/merchant.js +2 -0
  69. package/lib/module/types/interfaces/merchant.js.map +1 -0
  70. package/lib/module/types/interfaces/order.js +2 -0
  71. package/lib/module/types/interfaces/order.js.map +1 -0
  72. package/lib/module/types/interfaces/user.js +2 -0
  73. package/lib/module/types/interfaces/user.js.map +1 -0
  74. package/lib/module/types/utils/hasKey.js +8 -0
  75. package/lib/module/types/utils/hasKey.js.map +1 -0
  76. package/lib/module/types/utils/index.js +4 -0
  77. package/lib/module/types/utils/index.js.map +1 -0
  78. package/lib/typescript/deuna-sdk-react-native/src/DeunaLogs.d.ts +6 -0
  79. package/lib/typescript/deuna-sdk-react-native/src/DeunaLogs.d.ts.map +1 -0
  80. package/lib/typescript/deuna-sdk-react-native/src/DeunaSDK.d.ts +88 -0
  81. package/lib/typescript/deuna-sdk-react-native/src/DeunaSDK.d.ts.map +1 -0
  82. package/lib/typescript/deuna-sdk-react-native/src/components/DeunaWebView.d.ts +11 -0
  83. package/lib/typescript/deuna-sdk-react-native/src/components/DeunaWebView.d.ts.map +1 -0
  84. package/lib/typescript/deuna-sdk-react-native/src/components/DeunaWidget.d.ts +7 -0
  85. package/lib/typescript/deuna-sdk-react-native/src/components/DeunaWidget.d.ts.map +1 -0
  86. package/lib/typescript/deuna-sdk-react-native/src/components/NewTabWebView.d.ts +7 -0
  87. package/lib/typescript/deuna-sdk-react-native/src/components/NewTabWebView.d.ts.map +1 -0
  88. package/lib/typescript/deuna-sdk-react-native/src/components/WebViewLoader.d.ts +2 -0
  89. package/lib/typescript/deuna-sdk-react-native/src/components/WebViewLoader.d.ts.map +1 -0
  90. package/lib/typescript/deuna-sdk-react-native/src/controllers/BaseWebViewController.d.ts +83 -0
  91. package/lib/typescript/deuna-sdk-react-native/src/controllers/BaseWebViewController.d.ts.map +1 -0
  92. package/lib/typescript/deuna-sdk-react-native/src/controllers/ElementsWidgetController.d.ts +9 -0
  93. package/lib/typescript/deuna-sdk-react-native/src/controllers/ElementsWidgetController.d.ts.map +1 -0
  94. package/lib/typescript/deuna-sdk-react-native/src/controllers/OpenInNewTabController.d.ts +12 -0
  95. package/lib/typescript/deuna-sdk-react-native/src/controllers/OpenInNewTabController.d.ts.map +1 -0
  96. package/lib/typescript/deuna-sdk-react-native/src/controllers/PaymentWidgetController.d.ts +12 -0
  97. package/lib/typescript/deuna-sdk-react-native/src/controllers/PaymentWidgetController.d.ts.map +1 -0
  98. package/lib/typescript/deuna-sdk-react-native/src/helpers/Completer.d.ts +12 -0
  99. package/lib/typescript/deuna-sdk-react-native/src/helpers/Completer.d.ts.map +1 -0
  100. package/lib/typescript/deuna-sdk-react-native/src/helpers/getController.d.ts +22 -0
  101. package/lib/typescript/deuna-sdk-react-native/src/helpers/getController.d.ts.map +1 -0
  102. package/lib/typescript/deuna-sdk-react-native/src/index.d.ts +5 -0
  103. package/lib/typescript/deuna-sdk-react-native/src/index.d.ts.map +1 -0
  104. package/lib/typescript/deuna-sdk-react-native/src/interfaces/constants.d.ts +6 -0
  105. package/lib/typescript/deuna-sdk-react-native/src/interfaces/constants.d.ts.map +1 -0
  106. package/lib/typescript/deuna-sdk-react-native/src/interfaces/errors.d.ts +32 -0
  107. package/lib/typescript/deuna-sdk-react-native/src/interfaces/errors.d.ts.map +1 -0
  108. package/lib/typescript/deuna-sdk-react-native/src/interfaces/events/checkout.d.ts +46 -0
  109. package/lib/typescript/deuna-sdk-react-native/src/interfaces/events/checkout.d.ts.map +1 -0
  110. package/lib/typescript/deuna-sdk-react-native/src/interfaces/events/elements.d.ts +29 -0
  111. package/lib/typescript/deuna-sdk-react-native/src/interfaces/events/elements.d.ts.map +1 -0
  112. package/lib/typescript/deuna-sdk-react-native/src/interfaces/index.d.ts +4 -0
  113. package/lib/typescript/deuna-sdk-react-native/src/interfaces/index.d.ts.map +1 -0
  114. package/lib/typescript/deuna-sdk-react-native/src/interfaces/types.d.ts +15 -0
  115. package/lib/typescript/deuna-sdk-react-native/src/interfaces/types.d.ts.map +1 -0
  116. package/lib/typescript/deuna-sdk-react-native/src/types/base.d.ts +91 -0
  117. package/lib/typescript/deuna-sdk-react-native/src/types/base.d.ts.map +1 -0
  118. package/lib/typescript/deuna-sdk-react-native/src/types/env.d.ts +45 -0
  119. package/lib/typescript/deuna-sdk-react-native/src/types/env.d.ts.map +1 -0
  120. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildElementsLink.d.ts +3 -0
  121. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildElementsLink.d.ts.map +1 -0
  122. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildNextActionLink.d.ts +3 -0
  123. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildNextActionLink.d.ts.map +1 -0
  124. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildPaymentLink.d.ts +8 -0
  125. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildPaymentLink.d.ts.map +1 -0
  126. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildVoucherLink.d.ts +8 -0
  127. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/buildVoucherLink.d.ts.map +1 -0
  128. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/index.d.ts +7 -0
  129. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/index.d.ts.map +1 -0
  130. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/urlConfig.d.ts +34 -0
  131. package/lib/typescript/deuna-sdk-react-native/src/types/helpers/urlConfig.d.ts.map +1 -0
  132. package/lib/typescript/deuna-sdk-react-native/src/types/index.d.ts +5 -0
  133. package/lib/typescript/deuna-sdk-react-native/src/types/index.d.ts.map +1 -0
  134. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/callbacks.d.ts +38 -0
  135. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/callbacks.d.ts.map +1 -0
  136. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/customStyle.d.ts +156 -0
  137. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/customStyle.d.ts.map +1 -0
  138. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/index.d.ts +7 -0
  139. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/index.d.ts.map +1 -0
  140. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/initWidgetBase.d.ts +78 -0
  141. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/initWidgetBase.d.ts.map +1 -0
  142. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/merchant.d.ts +76 -0
  143. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/merchant.d.ts.map +1 -0
  144. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/order.d.ts +3 -0
  145. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/order.d.ts.map +1 -0
  146. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/user.d.ts +23 -0
  147. package/lib/typescript/deuna-sdk-react-native/src/types/interfaces/user.d.ts.map +1 -0
  148. package/lib/typescript/deuna-sdk-react-native/src/types/utils/hasKey.d.ts +2 -0
  149. package/lib/typescript/deuna-sdk-react-native/src/types/utils/hasKey.d.ts.map +1 -0
  150. package/lib/typescript/deuna-sdk-react-native/src/types/utils/index.d.ts +2 -0
  151. package/lib/typescript/deuna-sdk-react-native/src/types/utils/index.d.ts.map +1 -0
  152. package/lib/typescript/package.json +1 -0
  153. package/package.json +159 -0
  154. package/src/DeunaLogs.ts +17 -0
  155. package/src/DeunaSDK.ts +269 -0
  156. package/src/components/DeunaWebView.tsx +38 -0
  157. package/src/components/DeunaWidget.tsx +92 -0
  158. package/src/components/NewTabWebView.tsx +61 -0
  159. package/src/components/WebViewLoader.tsx +22 -0
  160. package/src/controllers/BaseWebViewController.ts +289 -0
  161. package/src/controllers/ElementsWidgetController.ts +78 -0
  162. package/src/controllers/OpenInNewTabController.ts +39 -0
  163. package/src/controllers/PaymentWidgetController.ts +118 -0
  164. package/src/helpers/Completer.ts +33 -0
  165. package/src/helpers/getController.ts +83 -0
  166. package/src/index.tsx +4 -0
  167. package/src/interfaces/constants.ts +5 -0
  168. package/src/interfaces/errors.ts +34 -0
  169. package/src/interfaces/events/checkout.ts +46 -0
  170. package/src/interfaces/events/elements.ts +29 -0
  171. package/src/interfaces/index.ts +3 -0
  172. package/src/interfaces/types.ts +13 -0
  173. package/src/types/base.ts +126 -0
  174. package/src/types/env.ts +51 -0
  175. package/src/types/helpers/buildElementsLink.ts +87 -0
  176. package/src/types/helpers/buildNextActionLink.ts +42 -0
  177. package/src/types/helpers/buildPaymentLink.ts +63 -0
  178. package/src/types/helpers/buildVoucherLink.ts +53 -0
  179. package/src/types/helpers/index.ts +11 -0
  180. package/src/types/helpers/urlConfig.ts +80 -0
  181. package/src/types/index.ts +4 -0
  182. package/src/types/interfaces/callbacks.ts +43 -0
  183. package/src/types/interfaces/customStyle.ts +189 -0
  184. package/src/types/interfaces/index.ts +6 -0
  185. package/src/types/interfaces/initWidgetBase.ts +97 -0
  186. package/src/types/interfaces/merchant.ts +79 -0
  187. package/src/types/interfaces/order.ts +1 -0
  188. package/src/types/interfaces/user.ts +22 -0
  189. package/src/types/utils/hasKey.ts +5 -0
  190. package/src/types/utils/index.ts +1 -0
package/package.json ADDED
@@ -0,0 +1,159 @@
1
+ {
2
+ "name": "@deuna/react-native-sdk",
3
+ "version": "1.0.0",
4
+ "description": "React Native SDK",
5
+ "source": "./src/index.tsx",
6
+ "main": "./lib/module/index.js",
7
+ "types": "./lib/typescript/deuna-sdk-react-native/src/index.d.ts",
8
+ "peerDependencies": {
9
+ "react": "*",
10
+ "react-native": "*",
11
+ "react-native-webview": "*"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./lib/typescript/deuna-sdk-react-native/src/index.d.ts",
16
+ "default": "./lib/module/index.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "src",
22
+ "lib",
23
+ "android",
24
+ "ios",
25
+ "cpp",
26
+ "*.podspec",
27
+ "react-native.config.js",
28
+ "!ios/build",
29
+ "!android/build",
30
+ "!android/gradle",
31
+ "!android/gradlew",
32
+ "!android/gradlew.bat",
33
+ "!android/local.properties",
34
+ "!**/__tests__",
35
+ "!**/__fixtures__",
36
+ "!**/__mocks__",
37
+ "!**/.*"
38
+ ],
39
+ "scripts": {
40
+ "copy-types": "bash copy-types.sh",
41
+ "example": "yarn workspace deuna-sdk-react-native-example",
42
+ "test": "jest",
43
+ "typecheck": "tsc",
44
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
45
+ "clean": "del-cli lib",
46
+ "prepare": "yarn copy-types && bob build",
47
+ "release": "release-it",
48
+ "example:install": "yarn prepare && yarn example install",
49
+ "example:android": "yarn example android",
50
+ "example:ios": "yarn example ios"
51
+ },
52
+ "keywords": [
53
+ "react-native",
54
+ "ios",
55
+ "android"
56
+ ],
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/darwinmorocho-deuna/deuna-sdk-react-native.git"
60
+ },
61
+ "author": "DEUNA <dmorocho@deuna.com> (https://github.com/darwinmorocho-deuna)",
62
+ "license": "MIT",
63
+ "bugs": {
64
+ "url": "https://github.com/darwinmorocho-deuna/deuna-sdk-react-native/issues"
65
+ },
66
+ "homepage": "https://github.com/darwinmorocho-deuna/deuna-sdk-react-native#readme",
67
+ "publishConfig": {
68
+ "registry": "https://registry.npmjs.org/"
69
+ },
70
+ "devDependencies": {
71
+ "@commitlint/config-conventional": "^19.6.0",
72
+ "@eslint/compat": "^1.2.7",
73
+ "@eslint/eslintrc": "^3.3.0",
74
+ "@eslint/js": "^9.22.0",
75
+ "@evilmartians/lefthook": "^1.5.0",
76
+ "@react-native/eslint-config": "^0.78.0",
77
+ "@release-it/conventional-changelog": "^9.0.2",
78
+ "@types/jest": "^29.5.5",
79
+ "@types/react": "^18.2.6",
80
+ "commitlint": "^19.6.1",
81
+ "del-cli": "^5.1.0",
82
+ "eslint": "^9.22.0",
83
+ "eslint-config-prettier": "^10.1.1",
84
+ "eslint-plugin-prettier": "^5.2.3",
85
+ "jest": "^29.7.0",
86
+ "prettier": "^3.0.3",
87
+ "react": "18.3.1",
88
+ "react-native": "0.76.9",
89
+ "react-native-builder-bob": "^0.40.6",
90
+ "react-native-webview": "^13.13.5",
91
+ "release-it": "^17.10.0",
92
+ "typescript": "^5.2.2"
93
+ },
94
+ "workspaces": [
95
+ "example"
96
+ ],
97
+ "packageManager": "yarn@3.6.1",
98
+ "jest": {
99
+ "preset": "react-native",
100
+ "modulePathIgnorePatterns": [
101
+ "<rootDir>/example/node_modules",
102
+ "<rootDir>/lib/"
103
+ ]
104
+ },
105
+ "commitlint": {
106
+ "extends": [
107
+ "@commitlint/config-conventional"
108
+ ]
109
+ },
110
+ "release-it": {
111
+ "git": {
112
+ "commitMessage": "chore: release ${version}",
113
+ "tagName": "v${version}"
114
+ },
115
+ "npm": {
116
+ "publish": true
117
+ },
118
+ "github": {
119
+ "release": true
120
+ },
121
+ "plugins": {
122
+ "@release-it/conventional-changelog": {
123
+ "preset": {
124
+ "name": "angular"
125
+ }
126
+ }
127
+ }
128
+ },
129
+ "prettier": {
130
+ "quoteProps": "consistent",
131
+ "singleQuote": true,
132
+ "tabWidth": 2,
133
+ "trailingComma": "es5",
134
+ "useTabs": false
135
+ },
136
+ "react-native-builder-bob": {
137
+ "source": "src",
138
+ "output": "lib",
139
+ "targets": [
140
+ [
141
+ "module",
142
+ {
143
+ "esm": true
144
+ }
145
+ ],
146
+ [
147
+ "typescript",
148
+ {
149
+ "project": "tsconfig.build.json"
150
+ }
151
+ ]
152
+ ]
153
+ },
154
+ "create-react-native-library": {
155
+ "languages": "js",
156
+ "type": "library",
157
+ "version": "0.49.8"
158
+ }
159
+ }
@@ -0,0 +1,17 @@
1
+ export class DeunaLogs {
2
+ static enable = true;
3
+
4
+ static info(tag: string, message: any) {
5
+ if (!DeunaLogs.enable) {
6
+ return;
7
+ }
8
+ console.info(`✅ DeunaSDK: ${tag}`, message);
9
+ }
10
+
11
+ static error(tag: string, message: any) {
12
+ if (!DeunaLogs.enable) {
13
+ return;
14
+ }
15
+ console.error(`❌ DeunaSDK: ${tag}`, message);
16
+ }
17
+ }
@@ -0,0 +1,269 @@
1
+ import {
2
+ BaseDeuna,
3
+ CustomStyles,
4
+ GetStateFn,
5
+ InitElementsWidgetParams,
6
+ InitializeParams,
7
+ InitNextActionWidgetParams,
8
+ InitPaymentWidgetParams,
9
+ InitVoucherWidgetParams,
10
+ IsValid,
11
+ Json,
12
+ PaymentWidgetCallbacks,
13
+ RefetchOrder,
14
+ SetCustomStyle,
15
+ State,
16
+ Submit,
17
+ SubmitResult,
18
+ VoucherWidgetCallbacks,
19
+ } from './types';
20
+ import {
21
+ BaseWebViewController,
22
+ DeunaWebViewController,
23
+ WebViewDelegate,
24
+ } from './controllers/BaseWebViewController';
25
+ import { PaymentWidgetController } from './controllers/PaymentWidgetController';
26
+ import { OpenInNewTabController } from './controllers/OpenInNewTabController';
27
+ import { getWidgetController } from './helpers/getController';
28
+ import { Completer } from './helpers/Completer';
29
+ import { ElementsWidgetController } from './controllers/ElementsWidgetController';
30
+ import { Mode, OnDownloadFile } from './interfaces/types';
31
+ import { Platform } from 'react-native';
32
+
33
+ export class DeunaSDK extends BaseDeuna {
34
+ constructor(private readonly config: InitializeParams) {
35
+ super();
36
+ }
37
+
38
+ mode: Mode | null = null;
39
+
40
+ setCustomStyleFn?: SetCustomStyle | undefined;
41
+ refetchOrderFn?: RefetchOrder | undefined;
42
+ getStateFn?: GetStateFn | undefined;
43
+ onSubmitFn?: Submit | undefined;
44
+ isValidFn?: IsValid | undefined;
45
+ closeFn?: (() => void) | undefined;
46
+
47
+ private listeners: Set<() => void> = new Set();
48
+ webViewController: DeunaWebViewController | null = null;
49
+ newTabWebViewController: BaseWebViewController | null = null;
50
+
51
+ modalDismissPromise: Completer<void> | null = null;
52
+ newTabModalDismissPromise: Completer<void> | null = null;
53
+
54
+ private get safeWebViewController(): DeunaWebViewController {
55
+ if (!this.webViewController) {
56
+ const errorMessage =
57
+ 'A variant of the init method must be called first. Please call initPaymentWidget, initVoucherWidget, or another init method before using this functionality.';
58
+ console.error(errorMessage);
59
+ throw new Error(errorMessage);
60
+ }
61
+ return this.webViewController;
62
+ }
63
+
64
+ getSessionId(): Promise<string> {
65
+ throw new Error('Method not implemented.');
66
+ }
67
+
68
+ static initialize(config: InitializeParams): DeunaSDK {
69
+ return new DeunaSDK(config);
70
+ }
71
+
72
+ /**
73
+ * Sets the DEUNA widget controller
74
+ * @param params - The parameters for the widget controller
75
+ * @param params.controller - The controller for the widget
76
+ * @param params.mode - The mode for the widget
77
+ */
78
+ private setWidgetController = (params: {
79
+ controller: DeunaWebViewController;
80
+ mode?: Mode;
81
+ }): void => {
82
+ const { controller, mode } = params;
83
+ this.mode = mode ?? Mode.MODAL;
84
+ if (this.mode === Mode.MODAL && Platform.OS === 'ios') {
85
+ this.modalDismissPromise = new Completer<void>();
86
+ }
87
+ this.webViewController = controller;
88
+ this.webViewController.delegate = this.buildDelegate();
89
+ this.notifyListeners();
90
+ };
91
+
92
+ /**
93
+ * Shows the payment widget
94
+ * @param props - The parameters for the payment widget controller
95
+ * @param props.mode - The mode for the widget
96
+ */
97
+ async initPaymentWidget(
98
+ props: Omit<InitPaymentWidgetParams, 'callbacks'> & {
99
+ mode?: Mode;
100
+ callbacks: PaymentWidgetCallbacks & OnDownloadFile;
101
+ }
102
+ ) {
103
+ this.setWidgetController({
104
+ controller: getWidgetController(this.config, {
105
+ widget: 'payment',
106
+ ...props,
107
+ }),
108
+ mode: props.mode,
109
+ });
110
+ }
111
+
112
+ /**
113
+ * Shows the elements widget
114
+ * @param props - The parameters for the elements widget controller
115
+ * @param props.mode - The mode for the widget
116
+ */
117
+ async initElements(
118
+ props: InitElementsWidgetParams & { mode?: Mode; sessionId?: string }
119
+ ) {
120
+ this.setWidgetController({
121
+ controller: getWidgetController(this.config, {
122
+ widget: 'elements',
123
+ ...props,
124
+ }),
125
+ mode: props.mode,
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Shows the next action widget
131
+ * @param props - The parameters for the next action widget controller
132
+ * @param props.mode - The mode for the widget
133
+ */
134
+ async initNextAction(props: InitNextActionWidgetParams & { mode: Mode }) {
135
+ this.setWidgetController({
136
+ controller: getWidgetController(this.config, {
137
+ widget: 'nextAction',
138
+ ...props,
139
+ }),
140
+ mode: props.mode,
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Shows the voucher widget
146
+ * @param props - The parameters for the voucher widget controller
147
+ * @param props.mode - The mode for the widget
148
+ */
149
+ async initVoucherWidget(
150
+ props: Omit<InitVoucherWidgetParams, 'callbacks'> & {
151
+ mode: Mode;
152
+ callbacks: VoucherWidgetCallbacks & OnDownloadFile;
153
+ }
154
+ ) {
155
+ this.setWidgetController({
156
+ controller: getWidgetController(this.config, {
157
+ widget: 'voucher',
158
+ ...props,
159
+ }),
160
+ mode: props.mode,
161
+ });
162
+ }
163
+
164
+ isValid = async (): Promise<boolean> => {
165
+ return this.safeWebViewController.isValid();
166
+ };
167
+
168
+ submit = async (): Promise<SubmitResult> => {
169
+ return this.safeWebViewController.submit();
170
+ };
171
+
172
+ setCustomStyle = async (style: Partial<CustomStyles>): Promise<void> => {
173
+ return this.safeWebViewController.setCustomStyle(style);
174
+ };
175
+
176
+ refetchOrder = async (): Promise<Json | null> => {
177
+ return this.safeWebViewController.refetchOrder();
178
+ };
179
+
180
+ getWidgetState = async (): Promise<State> => {
181
+ return this.safeWebViewController.getWidgetState();
182
+ };
183
+
184
+ /**
185
+ * Closes the DEUNA widget and releases the resources
186
+ */
187
+ close = async (): Promise<void> => {
188
+ if (this.webViewController instanceof PaymentWidgetController) {
189
+ this.webViewController.callbacks.onClosed?.(
190
+ this.webViewController.closedAction
191
+ );
192
+ } else if (this.webViewController instanceof ElementsWidgetController) {
193
+ this.webViewController.callbacks.onClosed?.(
194
+ this.webViewController.closedAction
195
+ );
196
+ }
197
+ this.onCloseNewTab();
198
+ await this.newTabModalDismissPromise?.wait;
199
+ this.newTabWebViewController?.dispose();
200
+
201
+ this.webViewController?.dispose();
202
+ // reset all prop
203
+ this.newTabWebViewController = null;
204
+ this.webViewController = null;
205
+ this.mode = null;
206
+ this.notifyListeners();
207
+
208
+ // if the widget was shown in modal mode, wait for the modal to be dismissed
209
+ await this.modalDismissPromise?.wait;
210
+ this.modalDismissPromise = null;
211
+ };
212
+
213
+ onModalDismissed = () => {
214
+ this.modalDismissPromise?.complete();
215
+ };
216
+
217
+ onNewTabDismissed = () => {
218
+ this.newTabModalDismissPromise?.complete();
219
+ };
220
+
221
+ addListener = (listener: () => void) => {
222
+ this.listeners.add(listener);
223
+ };
224
+
225
+ removeListener = (listener: () => void) => {
226
+ this.listeners.delete(listener);
227
+ };
228
+
229
+ notifyListeners = () => {
230
+ this.listeners.forEach((listener) => listener());
231
+ };
232
+
233
+ onCloseNewTab = () => {
234
+ if (this.webViewController) {
235
+ this.webViewController.redirectUrl = null;
236
+ }
237
+ this.newTabWebViewController?.dispose();
238
+ this.newTabWebViewController = null;
239
+ this.notifyListeners();
240
+ };
241
+
242
+ /**
243
+ * Builds the delegate for the DEUNA widget to listen to the events
244
+ * like when the user presses the close button or when the user
245
+ * opens a new tab.
246
+ * @returns The delegate for the DEUNA widget
247
+ */
248
+ buildDelegate = (): WebViewDelegate => {
249
+ return {
250
+ onOpenInNewTab: (url) => {
251
+ this.newTabWebViewController = new OpenInNewTabController(url);
252
+ if (Platform.OS === 'ios') {
253
+ this.newTabModalDismissPromise = new Completer<void>();
254
+ }
255
+ this.notifyListeners();
256
+ },
257
+ onCloseButtonPressed: () => {
258
+ // Close the payment widget when the user
259
+ // presses the close button
260
+ this.close();
261
+ },
262
+ onCloseSubWebView: () => {
263
+ // Close the new tab web view when the DEUNA widget
264
+ // emits an error event or when the purchase is successful
265
+ this.onCloseNewTab();
266
+ },
267
+ };
268
+ };
269
+ }
@@ -0,0 +1,38 @@
1
+ import { StyleSheet, View } from 'react-native';
2
+ import WebView from 'react-native-webview';
3
+ import { WebViewLoader } from './WebViewLoader';
4
+
5
+ interface DeunaWebViewProps {
6
+ url: string;
7
+ onWebView?: (webView: WebView) => void;
8
+ onMessage?: (event: any) => void;
9
+ onLoad?: () => void;
10
+ onError?: (error: any) => void;
11
+ }
12
+
13
+ export const DeunaWebView = (props: DeunaWebViewProps) => {
14
+ return (
15
+ <View style={styles.container}>
16
+ <WebView
17
+ ref={(webView) => {
18
+ if (webView && props.onWebView) {
19
+ props.onWebView(webView);
20
+ }
21
+ }}
22
+ source={{ uri: props.url }}
23
+ onMessage={props.onMessage}
24
+ onLoad={() => {
25
+ props.onLoad?.();
26
+ }}
27
+ startInLoadingState
28
+ renderLoading={() => <WebViewLoader />}
29
+ javaScriptEnabled={true}
30
+ onError={props.onError}
31
+ setSupportMultipleWindows={false}
32
+ javaScriptCanOpenWindowsAutomatically={false}
33
+ />
34
+ </View>
35
+ );
36
+ };
37
+
38
+ const styles = StyleSheet.create({ container: { flex: 1 } });
@@ -0,0 +1,92 @@
1
+ import { Modal, SafeAreaView, StyleSheet, View } from 'react-native';
2
+ import { useEffect, useRef, useState } from 'react';
3
+
4
+ import { DeunaSDK } from '../DeunaSDK';
5
+ import { DeunaWebView } from './DeunaWebView';
6
+ import { NewTabWebView } from './NewTabWebView';
7
+ import { DeunaWebViewController } from '../controllers/BaseWebViewController';
8
+ import { Mode } from '../interfaces/types';
9
+
10
+ interface DeunaWidgetProps {
11
+ instance: DeunaSDK;
12
+ }
13
+
14
+ export const DeunaWidget = (props: DeunaWidgetProps) => {
15
+ const { instance } = props;
16
+ const instanceRef = useRef(instance);
17
+ const [mode, setMode] = useState<Mode | null>(instance.mode);
18
+
19
+ useEffect(() => {
20
+ instanceRef.current = instance;
21
+ }, [instance]);
22
+
23
+ // Listen when the DeunaSDK instance configuration
24
+ // has changed
25
+ useEffect(() => {
26
+ const listener = () => {
27
+ setMode(instanceRef.current.mode);
28
+ };
29
+
30
+ instanceRef.current.addListener(listener);
31
+
32
+ return () => {
33
+ instanceRef.current.removeListener(listener);
34
+ instanceRef.current.webViewController?.dispose();
35
+ };
36
+ }, []);
37
+
38
+ const isModal = mode === Mode.MODAL;
39
+ const isEmbedded = mode === Mode.EMBEDDED;
40
+
41
+ /**
42
+ * This function is used to close the widget
43
+ */
44
+ const onClose = () => {
45
+ const controller = instanceRef.current
46
+ .webViewController as DeunaWebViewController;
47
+ controller.closedAction = 'userAction';
48
+ instanceRef.current.close();
49
+ };
50
+
51
+ // render the widget if mode is not null
52
+ return (
53
+ <>
54
+ <Modal
55
+ presentationStyle="pageSheet"
56
+ animationType="slide"
57
+ onRequestClose={onClose}
58
+ onDismiss={instanceRef.current.onModalDismissed}
59
+ visible={isModal}
60
+ >
61
+ {isModal && (
62
+ <SafeAreaView style={styles.container}>
63
+ <View style={styles.container}>
64
+ <DeunaWebView
65
+ url={instanceRef.current.webViewController?.url ?? ''}
66
+ onWebView={instanceRef.current.webViewController?.setWebView}
67
+ onMessage={instanceRef.current.webViewController?.onMessage}
68
+ onLoad={instanceRef.current.webViewController?.onLoad}
69
+ onError={instanceRef.current.webViewController?.onError}
70
+ />
71
+ <NewTabWebView instance={instanceRef.current} />
72
+ </View>
73
+ </SafeAreaView>
74
+ )}
75
+ </Modal>
76
+
77
+ {isEmbedded && <NewTabWebView instance={instanceRef.current} />}
78
+
79
+ {isEmbedded && (
80
+ <DeunaWebView
81
+ url={instanceRef.current.webViewController?.url ?? ''}
82
+ onWebView={instanceRef.current.webViewController?.setWebView}
83
+ onMessage={instanceRef.current.webViewController?.onMessage}
84
+ onLoad={instanceRef.current.webViewController?.onLoad}
85
+ onError={instanceRef.current.webViewController?.onError}
86
+ />
87
+ )}
88
+ </>
89
+ );
90
+ };
91
+
92
+ const styles = StyleSheet.create({ container: { flex: 1 } });
@@ -0,0 +1,61 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { DeunaSDK } from '../DeunaSDK';
3
+ import { Modal, SafeAreaView, StyleSheet } from 'react-native';
4
+ import { DeunaWebView } from './DeunaWebView';
5
+
6
+ interface NewTabWebViewProps {
7
+ instance: DeunaSDK;
8
+ }
9
+
10
+ export const NewTabWebView = (props: NewTabWebViewProps) => {
11
+ const { instance } = props;
12
+ const instanceRef = useRef<DeunaSDK>(instance);
13
+ const [visible, setVisible] = useState(false);
14
+
15
+ useEffect(() => {
16
+ instanceRef.current = instance;
17
+ }, [instance]);
18
+
19
+ // Listen when the DeunaSDK instance configuration
20
+ // has changed
21
+ useEffect(() => {
22
+ const ref = instanceRef.current;
23
+ const listener = () => {
24
+ const isVisible = !!ref.newTabWebViewController;
25
+ setVisible(isVisible);
26
+ };
27
+
28
+ instanceRef.current.addListener(listener);
29
+
30
+ return () => {
31
+ ref.removeListener(listener);
32
+ ref.newTabWebViewController?.dispose();
33
+ };
34
+ }, []);
35
+
36
+ const newTabController = instanceRef.current.newTabWebViewController;
37
+
38
+ return (
39
+ <Modal
40
+ presentationStyle="pageSheet"
41
+ visible={visible}
42
+ animationType="slide"
43
+ onRequestClose={instanceRef.current.onCloseNewTab}
44
+ onDismiss={instanceRef.current.onNewTabDismissed}
45
+ >
46
+ {visible && (
47
+ <SafeAreaView style={styles.container}>
48
+ <DeunaWebView
49
+ url={newTabController?.url ?? ''}
50
+ onWebView={newTabController?.setWebView}
51
+ onMessage={newTabController?.onMessage}
52
+ onLoad={newTabController?.onLoad}
53
+ onError={newTabController?.onError}
54
+ />
55
+ </SafeAreaView>
56
+ )}
57
+ </Modal>
58
+ );
59
+ };
60
+
61
+ const styles = StyleSheet.create({ container: { flex: 1 } });
@@ -0,0 +1,22 @@
1
+ import { ActivityIndicator, StyleSheet, View } from 'react-native';
2
+
3
+ export const WebViewLoader = () => {
4
+ return (
5
+ <View style={styles.container}>
6
+ <ActivityIndicator size="small" />
7
+ </View>
8
+ );
9
+ };
10
+
11
+ const styles = StyleSheet.create({
12
+ container: {
13
+ position: 'absolute',
14
+ top: 0,
15
+ left: 0,
16
+ right: 0,
17
+ bottom: 0,
18
+ justifyContent: 'center',
19
+ alignItems: 'center',
20
+ backgroundColor: '#FFFFFF',
21
+ },
22
+ });