airbridge-react-native-sdk-restricted 2.8.9 → 4.1.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 (268) hide show
  1. package/.github/workflows/build.yml +249 -159
  2. package/.github/workflows/documentation.yml +76 -0
  3. package/.github/workflows/qa.yml +187 -0
  4. package/.github/workflows/release.yml +26 -0
  5. package/airbridge-react-native-sdk-restricted.podspec +10 -7
  6. package/airbridge_sdk.json +4 -0
  7. package/android/build.gradle +22 -5
  8. package/android/{copy-config.gradle → copy-airbridge-json.gradle} +2 -2
  9. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeReactNative.kt +141 -0
  10. package/android/src/main/java/co/ab180/airbridge/reactnative/common/AirbridgeLifecycleIntegration.kt +7 -0
  11. package/android/src/main/java/co/ab180/airbridge/reactnative/extension/AirbridgeOptionBuilderApply.kt +79 -0
  12. package/android/src/main/java/co/ab180/airbridge/reactnative/extension/JSONConvert.kt +33 -0
  13. package/android/src/main/java/co/ab180/airbridge/reactnative/module/AttributionInteractor.kt +54 -0
  14. package/android/src/main/java/co/ab180/airbridge/reactnative/module/DeeplinkInteractor.kt +45 -0
  15. package/android/src/main/java/co/ab180/airbridge/reactnative/module/EventInteractor.kt +22 -0
  16. package/android/src/main/java/co/ab180/airbridge/reactnative/module/FetchInteractor.kt +51 -0
  17. package/android/src/main/java/co/ab180/airbridge/reactnative/module/PlacementInteractor.kt +56 -0
  18. package/android/src/main/java/co/ab180/airbridge/reactnative/module/RegisterInteractor.kt +108 -0
  19. package/android/src/main/java/co/ab180/airbridge/reactnative/module/SwitchInteractor.kt +43 -0
  20. package/android/src/main/java/co/ab180/airbridge/reactnative/module/WebInterfaceInteractor.kt +24 -0
  21. package/build/document/.nojekyll +1 -0
  22. package/build/document/assets/highlight.css +22 -0
  23. package/build/document/assets/icons.js +18 -0
  24. package/build/document/assets/icons.svg +1 -0
  25. package/build/document/assets/main.js +60 -0
  26. package/build/document/assets/navigation.js +1 -0
  27. package/build/document/assets/search.js +1 -0
  28. package/build/document/assets/style.css +1448 -0
  29. package/build/document/classes/Airbridge.html +113 -0
  30. package/build/document/classes/AirbridgeAttribute.html +49 -0
  31. package/build/document/classes/AirbridgeCategory.html +28 -0
  32. package/build/document/index.html +8 -0
  33. package/build/document/modules.html +4 -0
  34. package/build/source/Airbridge.d.ts +230 -0
  35. package/build/source/Airbridge.js +277 -0
  36. package/build/source/Airbridge.js.map +1 -0
  37. package/build/source/architecture/Interactor.d.ts +2 -0
  38. package/build/source/architecture/Interactor.js +7 -0
  39. package/build/source/architecture/Interactor.js.map +1 -0
  40. package/build/source/architecture/module.d.ts +1 -0
  41. package/build/source/architecture/module.js +2 -0
  42. package/build/source/architecture/module.js.map +1 -0
  43. package/build/source/constant/AirbridgeAttribute.d.ts +51 -0
  44. package/build/source/constant/AirbridgeAttribute.js +144 -0
  45. package/build/source/constant/AirbridgeAttribute.js.map +1 -0
  46. package/build/source/constant/AirbridgeCategory.d.ts +30 -0
  47. package/build/source/constant/AirbridgeCategory.js +81 -0
  48. package/build/source/constant/AirbridgeCategory.js.map +1 -0
  49. package/build/source/module/Attribution.d.ts +16 -0
  50. package/build/source/module/Attribution.js +39 -0
  51. package/build/source/module/Attribution.js.map +1 -0
  52. package/build/source/module/Deeplink.d.ts +17 -0
  53. package/build/source/module/Deeplink.js +40 -0
  54. package/build/source/module/Deeplink.js.map +1 -0
  55. package/build/source/module/Event.d.ts +14 -0
  56. package/build/source/module/Event.js +50 -0
  57. package/build/source/module/Event.js.map +1 -0
  58. package/build/source/module/Fetch.d.ts +19 -0
  59. package/build/source/module/Fetch.js +100 -0
  60. package/build/source/module/Fetch.js.map +1 -0
  61. package/build/source/module/Placement.d.ts +18 -0
  62. package/build/source/module/Placement.js +95 -0
  63. package/build/source/module/Placement.js.map +1 -0
  64. package/build/source/module/Register.d.ts +49 -0
  65. package/build/source/module/Register.js +138 -0
  66. package/build/source/module/Register.js.map +1 -0
  67. package/build/source/module/Switch.d.ts +24 -0
  68. package/build/source/module/Switch.js +39 -0
  69. package/build/source/module/Switch.js.map +1 -0
  70. package/build/source/module/WebInterface.d.ts +16 -0
  71. package/build/source/module/WebInterface.js +46 -0
  72. package/build/source/module/WebInterface.js.map +1 -0
  73. package/build/source/module.d.ts +3 -0
  74. package/build/source/module.js +4 -0
  75. package/build/source/module.js.map +1 -0
  76. package/build/source/utility/check.d.ts +13 -0
  77. package/build/source/utility/check.js +15 -0
  78. package/build/source/utility/check.js.map +1 -0
  79. package/build/source/utility/compute.d.ts +3 -0
  80. package/build/source/utility/compute.js +5 -0
  81. package/build/source/utility/compute.js.map +1 -0
  82. package/build/source/utility/create.d.ts +5 -0
  83. package/build/source/utility/create.js +12 -0
  84. package/build/source/utility/create.js.map +1 -0
  85. package/build/source/utility/extract.d.ts +3 -0
  86. package/build/source/utility/extract.js +4 -0
  87. package/build/source/utility/extract.js.map +1 -0
  88. package/build/source/utility/json.d.ts +11 -0
  89. package/build/source/utility/json.js +137 -0
  90. package/build/source/utility/json.js.map +1 -0
  91. package/build/source/utility/log.d.ts +4 -0
  92. package/build/source/utility/log.js +9 -0
  93. package/build/source/utility/log.js.map +1 -0
  94. package/changelog.md +5 -3
  95. package/ios/AirbridgeReactNative/AirbridgeReactNative.h +23 -0
  96. package/ios/AirbridgeReactNative/AirbridgeReactNative.m +36 -0
  97. package/ios/AirbridgeReactNative/AirbridgeReactNative.swift +95 -0
  98. package/ios/AirbridgeReactNative/Extension/AirbridgeOptionBuilderApply.swift +86 -0
  99. package/ios/AirbridgeReactNative/Extension/DataFromHex.swift +21 -0
  100. package/ios/AirbridgeReactNative/Extension/Logger.swift +62 -0
  101. package/ios/AirbridgeReactNative/Module/AirbridgeModuleExtern.m +133 -0
  102. package/ios/AirbridgeReactNative/Module/AttributionInteractor.swift +43 -0
  103. package/ios/AirbridgeReactNative/Module/DeeplinkInteractor.swift +49 -0
  104. package/ios/AirbridgeReactNative/Module/EventInteractor.swift +26 -0
  105. package/ios/AirbridgeReactNative/Module/FetchInteractor.swift +66 -0
  106. package/ios/AirbridgeReactNative/Module/PlacementInteractor.swift +72 -0
  107. package/ios/AirbridgeReactNative/Module/RegisterInteractor.swift +104 -0
  108. package/ios/AirbridgeReactNative/Module/SwitchInteractor.swift +48 -0
  109. package/ios/AirbridgeReactNative/Module/WebInterfaceInteractor.swift +30 -0
  110. package/ios/{copy-config.rb → copy-airbridge-json.rb} +1 -1
  111. package/package.json +18 -27
  112. package/qa/Gemfile +3 -4
  113. package/qa/Gemfile.lock +28 -17
  114. package/qa/airbridge_qa.json +6 -0
  115. package/qa/android/app/build.gradle +30 -26
  116. package/qa/android/app/src/main/AndroidManifest.xml +159 -7
  117. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/ConfigurationLoader.kt +5 -5
  118. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/MainActivity.kt +2 -2
  119. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/IdentifiersInteractor.kt +8 -17
  120. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/InstallReferrerInteractor.kt +13 -22
  121. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/ModuleInjector.kt +1 -2
  122. package/qa/android/app/src/main/res/values/airbridge.xml +16 -0
  123. package/qa/android/build.gradle +4 -2
  124. package/qa/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  125. package/qa/android/gradle.properties +0 -2
  126. package/qa/android/gradlew +1 -1
  127. package/qa/android/settings.gradle +3 -1
  128. package/qa/ios/AirbridgeQA/AirbridgeQA.entitlements +11 -0
  129. package/qa/ios/AirbridgeQA/AppDelegate.mm +40 -30
  130. package/qa/ios/AirbridgeQA/DeviceInfoInteractor.swift +0 -1
  131. package/qa/ios/AirbridgeQA/IdentifiersInteractor.swift +4 -8
  132. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x.png +0 -0
  133. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png +0 -0
  134. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-20@3x.png +0 -0
  135. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png +0 -0
  136. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-29.png +0 -0
  137. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x.png +0 -0
  138. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png +0 -0
  139. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-29@3x.png +0 -0
  140. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png +0 -0
  141. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x.png +0 -0
  142. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png +0 -0
  143. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-40@3x.png +0 -0
  144. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png +0 -0
  145. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png +0 -0
  146. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png +0 -0
  147. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png +0 -0
  148. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png +0 -0
  149. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png +0 -0
  150. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon@3x.png +0 -0
  151. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png +0 -0
  152. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/AppIcon~ipad.png +0 -0
  153. package/qa/ios/AirbridgeQA/Images.xcassets/AppIcon.appiconset/Contents.json +113 -32
  154. package/qa/ios/AirbridgeQA.xcodeproj/project.pbxproj +47 -29
  155. package/qa/ios/InternalLibrary/airbridge-ios-sdk-qa-library.podspec +32 -0
  156. package/qa/ios/InternalLibrary/airbridge-ios-sdk-restricted.podspec +32 -0
  157. package/qa/ios/Library/airbridge-ios-sdk-qa-library.podspec +6 -1
  158. package/qa/ios/Podfile +13 -1
  159. package/qa/ios/Podfile.lock +678 -313
  160. package/qa/ios/Script/prepare-build-parameter.rb +23 -0
  161. package/qa/metro.config.js +5 -2
  162. package/qa/package-lock.json +3360 -1435
  163. package/qa/package.json +29 -30
  164. package/qa/source/App.js +11 -5
  165. package/qa/source/common/FCMService.js +39 -15
  166. package/qa/source/navigations/Stack.js +8 -1
  167. package/qa/source/pages/AppInfo.js +40 -0
  168. package/qa/source/pages/Browse.js +16 -19
  169. package/qa/source/pages/DeviceInfo.js +10 -4
  170. package/qa/source/pages/Event.js +70 -60
  171. package/qa/source/pages/Home.js +77 -17
  172. package/qa/source/pages/Identifiers.js +10 -6
  173. package/qa/source/pages/Placement.js +3 -3
  174. package/qa/source/pages/Skad.js +76 -0
  175. package/qa/source/pages/UserInfo.js +47 -28
  176. package/readme.md +6 -6
  177. package/script/BuildDocument.sh +10 -0
  178. package/{scripts/build-qa.sh → script/BuildQA.sh} +5 -4
  179. package/script/BuildSource.sh +14 -0
  180. package/script/ChangeInternalSDK.sh +22 -0
  181. package/script/ChangeProductionSDK.sh +37 -0
  182. package/script/ChangeRestricted.sh +34 -0
  183. package/script/PrepareBuildParameter.sh +28 -0
  184. package/source/Airbridge.ts +340 -0
  185. package/source/architecture/Interactor.ts +10 -0
  186. package/source/architecture/module.ts +1 -0
  187. package/source/constant/AirbridgeAttribute.ts +188 -0
  188. package/source/constant/AirbridgeCategory.ts +104 -0
  189. package/source/module/Attribution.ts +4 -8
  190. package/source/module/Deeplink.ts +59 -0
  191. package/source/module/Event.ts +71 -0
  192. package/source/module/Fetch.ts +137 -0
  193. package/source/module/Placement.ts +134 -0
  194. package/source/module/Register.ts +203 -0
  195. package/source/module/Switch.ts +61 -0
  196. package/source/module/WebInterface.ts +55 -0
  197. package/source/module.ts +3 -0
  198. package/source/tsconfig.json +14 -0
  199. package/source/utility/check.ts +46 -0
  200. package/source/utility/compute.ts +9 -0
  201. package/source/utility/create.ts +12 -0
  202. package/source/utility/extract.ts +5 -0
  203. package/source/utility/json.ts +180 -0
  204. package/source/utility/log.ts +14 -0
  205. package/test/jest.json +13 -0
  206. package/test/mock.ts +112 -0
  207. package/test/module/Deeplink.test.ts +29 -0
  208. package/test/tsconfig.json +8 -0
  209. package/.eslintrc.json +0 -44
  210. package/.gitattributes +0 -1
  211. package/.github/actions/add-github-check/action.yml +0 -78
  212. package/.github/actions/add-github-comment/action.yml +0 -48
  213. package/.github/actions/add-slack-message/action.yml +0 -32
  214. package/.github/actions/edit-github-check/action.yml +0 -59
  215. package/.github/actions/edit-github-comment/action.yml +0 -41
  216. package/.github/workflows/release-restricted.yml +0 -35
  217. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeAttribution.java +0 -78
  218. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeDeeplink.java +0 -97
  219. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeEvent.java +0 -76
  220. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeLifecycle.java +0 -31
  221. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeLifecycleIntegration.java +0 -8
  222. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgePlacement.java +0 -42
  223. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeRN.java +0 -112
  224. package/android/src/main/java/co/ab180/airbridge/reactnative/AirbridgeState.java +0 -174
  225. package/android/src/main/java/co/ab180/airbridge/reactnative/ConfigReader.java +0 -154
  226. package/android/src/main/java/co/ab180/airbridge/reactnative/Get.java +0 -84
  227. package/index.d.ts +0 -338
  228. package/index.js +0 -8
  229. package/ios/AirbridgeRN/ARNConfigReader.h +0 -19
  230. package/ios/AirbridgeRN/ARNConfigReader.m +0 -80
  231. package/ios/AirbridgeRN/ARNGet.h +0 -20
  232. package/ios/AirbridgeRN/ARNGet.m +0 -40
  233. package/ios/AirbridgeRN/ARNHex.h +0 -16
  234. package/ios/AirbridgeRN/ARNHex.m +0 -44
  235. package/ios/AirbridgeRN/AirbridgeAttribution.h +0 -19
  236. package/ios/AirbridgeRN/AirbridgeAttribution.m +0 -47
  237. package/ios/AirbridgeRN/AirbridgeDeeplink.h +0 -20
  238. package/ios/AirbridgeRN/AirbridgeDeeplink.m +0 -59
  239. package/ios/AirbridgeRN/AirbridgeEvent.h +0 -17
  240. package/ios/AirbridgeRN/AirbridgeEvent.m +0 -63
  241. package/ios/AirbridgeRN/AirbridgePlacement.h +0 -17
  242. package/ios/AirbridgeRN/AirbridgePlacement.m +0 -38
  243. package/ios/AirbridgeRN/AirbridgeRN.h +0 -71
  244. package/ios/AirbridgeRN/AirbridgeRN.m +0 -83
  245. package/ios/AirbridgeRN/AirbridgeState.h +0 -17
  246. package/ios/AirbridgeRN/AirbridgeState.m +0 -94
  247. package/ios/AirbridgeRN.xcodeproj/project.pbxproj +0 -417
  248. package/qa/android/app/src/main/java/co/ab180/airbridge/qa/application/module/UserInfoInteractor.kt +0 -74
  249. package/qa/ios/AirbridgeQA/UserInfoInteractor.m +0 -57
  250. package/qa/ios/AirbridgeQA/UserInfoInteractor.swift +0 -49
  251. package/qa/source/pages/appInfo.js +0 -22
  252. package/scripts/addiOSFramework.js +0 -48
  253. package/scripts/change_restricted.sh +0 -21
  254. package/scripts/update_native_version.sh +0 -104
  255. package/src/Airbridge.js +0 -82
  256. package/src/Deeplink.js +0 -75
  257. package/src/Event.js +0 -38
  258. package/src/Placement.js +0 -56
  259. package/src/State.js +0 -175
  260. package/src/WebInterface.js +0 -135
  261. package/src/tool/Log.js +0 -40
  262. package/src/tool/_.js +0 -56
  263. package/src/type/AirbridgeAttributes.js +0 -40
  264. package/src/type/AirbridgeCategory.js +0 -35
  265. package/src/type/AirbridgeProduct.js +0 -18
  266. package/src/typedef/EventOption.js +0 -9
  267. package/src/typedef/Product.js +0 -10
  268. package/src/typedef/User.js +0 -9
@@ -0,0 +1,187 @@
1
+ name: qa
2
+
3
+ on:
4
+ pull_request:
5
+ types: [labeled]
6
+ workflow_dispatch:
7
+ inputs:
8
+ android_device:
9
+ description: android Device to QA
10
+ type: string
11
+ required: false
12
+ android_suite:
13
+ description: android Suite to QA (s09 or s09,s10 or ...)
14
+ type: string
15
+ required: false
16
+ ios_device:
17
+ description: iOS Device to QA
18
+ type: string
19
+ required: false
20
+ ios_suite:
21
+ description: iOS Suite to QA (s09 or s09,s10 or ...)
22
+ type: string
23
+ required: false
24
+
25
+ env:
26
+ TRIGGER: ${{ github.event_name }}
27
+ TAG: ${{
28
+ format(
29
+ '@{0} {1}',
30
+ github.event.pull_request.user.login || github.actor,
31
+ github.event_name == 'pull_request' && join(github.event.pull_request.requested_reviewers.*.login, '') != ''
32
+ && format('@{0}', join(github.event.pull_request.requested_reviewers.*.login, ' @'))
33
+ || ''
34
+ )
35
+ }}
36
+
37
+ jobs:
38
+ prepare:
39
+ runs-on: ubuntu-latest
40
+ if: |
41
+ (
42
+ github.event_name == 'pull_request'
43
+ && github.event.label.name == '!QA'
44
+ )
45
+ || (github.event_name == 'workflow_dispatch')
46
+
47
+ outputs:
48
+ comment-id: ${{ steps.report-queue-github-comment.outputs.comment-id }}
49
+ android-option: ${{ steps.parse-android-option.outputs.option || '{}' }}
50
+ ios-option: ${{ steps.parse-ios-option.outputs.option || '{}' }}
51
+
52
+ steps:
53
+ - name: Checkout
54
+ uses: actions/checkout@v4
55
+
56
+ - name: Parse android option
57
+ id: parse-android-option
58
+ if: env.TRIGGER == 'pull_request'
59
+ uses: ab180/airbridge-sdk-tool/action/parse-qa-option-from-github-comment@v1
60
+ with:
61
+ prefix: 'android-'
62
+
63
+ - name: Parse iOS option
64
+ id: parse-ios-option
65
+ if: env.TRIGGER == 'pull_request'
66
+ uses: ab180/airbridge-sdk-tool/action/parse-qa-option-from-github-comment@v1
67
+ with:
68
+ prefix: 'ios-'
69
+
70
+ - name: Report queue to GitHub comment
71
+ id: report-queue-github-comment
72
+ if: env.TRIGGER == 'pull_request'
73
+ uses: ab180/airbridge-sdk-tool/action/add-github-comment@v1
74
+ with:
75
+ comment: QA is started to trigger.
76
+
77
+ build:
78
+ needs: [prepare]
79
+ uses: ./.github/workflows/build.yml
80
+ secrets: inherit
81
+
82
+ trigger-qa:
83
+ runs-on: ubuntu-latest
84
+ needs: [prepare, build]
85
+ env:
86
+ ANDROID_DEVICE: ${{
87
+ inputs.android_device
88
+ || fromJson(needs.prepare.outputs.android-option)['device']
89
+ }}
90
+ ANDROID_SUITE: ${{
91
+ inputs.android_suite
92
+ || fromJson(needs.prepare.outputs.android-option)['suite']
93
+ }}
94
+ IOS_DEVICE: ${{
95
+ inputs.ios_device
96
+ || fromJson(needs.prepare.outputs.ios-option)['device']
97
+ }}
98
+ IOS_SUITE: ${{
99
+ inputs.ios_suite
100
+ || fromJson(needs.prepare.outputs.ios-option)['suite']
101
+ }}
102
+ steps:
103
+ - name: Trigger android QA
104
+ uses: ab180/airbridge-automation/.github/actions/trigger-sdk-qa@main
105
+ with:
106
+ option: |
107
+ {
108
+ "os": "android",
109
+ "device": "${{ env.ANDROID_DEVICE }}",
110
+ "suite": "${{ env.ANDROID_SUITE }}",
111
+ "sdkName": "${{ github.event.repository.name }}",
112
+ "sdkBuildNumber": "${{ needs.build.outputs.build-number }}",
113
+ "sdkVersion": "v4",
114
+ "sdkDownloadURL": "${{ needs.build.outputs.qa-android-application-download-url }}",
115
+ "pullRequestTitle": "${{ env.TRIGGER == 'pull_request' && github.event.pull_request.title || '' }}",
116
+ "pullRequestURL": "${{ env.TRIGGER == 'pull_request' && github.event.pull_request.html_url || '' }}",
117
+ "githubTag": "${{ env.TAG }}"
118
+ }
119
+ github-app-id: ${{ secrets.SDK_TEAM_APP_ID }}
120
+ github-app-private-key: ${{ secrets.SDK_TEAM_APP_PRIVATE_KEY }}
121
+ github-app-owner: ab180
122
+
123
+ - name: Trigger ios QA
124
+ uses: ab180/airbridge-automation/.github/actions/trigger-sdk-qa@main
125
+ with:
126
+ option: |
127
+ {
128
+ "os": "ios",
129
+ "device": "${{ env.IOS_DEVICE }}",
130
+ "suite": "${{ env.IOS_SUITE }}",
131
+ "sdkName": "${{ github.event.repository.name }}",
132
+ "sdkBuildNumber": "${{ needs.build.outputs.build-number }}",
133
+ "sdkVersion": "v4",
134
+ "sdkDownloadURL": "${{ needs.build.outputs.qa-ios-application-download-url }}",
135
+ "pullRequestTitle": "${{ env.TRIGGER == 'pull_request' && github.event.pull_request.title || '' }}",
136
+ "pullRequestURL": "${{ env.TRIGGER == 'pull_request' && github.event.pull_request.html_url || '' }}",
137
+ "githubTag": "${{ env.TAG }}"
138
+ }
139
+ github-app-id: ${{ secrets.SDK_TEAM_APP_ID }}
140
+ github-app-private-key: ${{ secrets.SDK_TEAM_APP_PRIVATE_KEY }}
141
+ github-app-owner: ab180
142
+
143
+ report:
144
+ runs-on: ubuntu-latest
145
+ needs:
146
+ - prepare
147
+ - build
148
+ - trigger-qa
149
+ if: ${{ always() && needs.prepare.result != 'skipped' }}
150
+
151
+ steps:
152
+ - name: Checkout
153
+ uses: actions/checkout@v4
154
+
155
+ - name: Report success to GitHub comment
156
+ if: ${{ env.TRIGGER == 'pull_request' && !contains(needs.*.result, 'failure') }}
157
+ uses: ab180/airbridge-sdk-tool/action/edit-github-comment@v1
158
+ with:
159
+ comment-id: ${{ needs.prepare.outputs.comment-id }}
160
+ comment: 'QA of SDK (${{ env.BUILD_NUMBER }}) is succeed to trigger. Result will be delivered to [#sdk-judgment-day](https://teamab180.slack.com/archives/C04R9RN7D4M).'
161
+ env:
162
+ BUILD_NUMBER: ${{ needs.build.outputs.build-number }}
163
+
164
+ - name: Report failure to GitHub comment
165
+ if: ${{ env.TRIGGER == 'pull_request' && contains(needs.*.result, 'failure') }}
166
+ uses: ab180/airbridge-sdk-tool/action/edit-github-comment@v1
167
+ with:
168
+ comment-id: ${{ needs.prepare.outputs.comment-id }}
169
+ comment: 'QA of SDK (${{ env.BUILD_NUMBER }}) is failed to trigger.'
170
+ env:
171
+ BUILD_NUMBER: ${{ needs.build.outputs.build-number }}
172
+
173
+ finish:
174
+ runs-on: ubuntu-latest
175
+ needs:
176
+ - prepare
177
+ - report
178
+ if: ${{ always() && needs.prepare.result != 'skipped' }}
179
+ steps:
180
+ - name: Checkout
181
+ uses: actions/checkout@v4
182
+
183
+ - name: Remove GitHub label
184
+ if: ${{ env.TRIGGER == 'pull_request' }}
185
+ uses: ab180/airbridge-sdk-tool/action/remove-github-label@v1
186
+ with:
187
+ label: '!QA'
@@ -30,3 +30,29 @@ jobs:
30
30
  env:
31
31
  NODE_AUTH_TOKEN: ${{ secrets.SDK_TEAM_NPM_AUTOMATION_TOKEN }}
32
32
  run: npm publish
33
+
34
+ release-restricted:
35
+ runs-on: ubuntu-latest
36
+ if: |
37
+ github.event.pull_request.merged == true
38
+
39
+ steps:
40
+ - name: Checkout
41
+ uses: actions/checkout@v3
42
+
43
+ - name: Prepare node
44
+ uses: actions/setup-node@v3
45
+ with:
46
+ node-version: 18
47
+ registry-url: 'https://registry.npmjs.org'
48
+
49
+ - name: Install dependencies
50
+ run: npm ci
51
+
52
+ - name: change restricted
53
+ run: sh script/ChangeRestricted.sh
54
+
55
+ - name: Publish
56
+ env:
57
+ NODE_AUTH_TOKEN: ${{ secrets.SDK_TEAM_NPM_AUTOMATION_TOKEN }}
58
+ run: npm publish
@@ -1,8 +1,11 @@
1
1
  require 'json'
2
2
  require 'pathname'
3
- require_relative 'ios/copy-config.rb'
3
+ require_relative 'ios/copy-airbridge-json.rb'
4
+
5
+ current_directory=File.dirname(__FILE__)
6
+ package = JSON.parse(File.read(File.join(current_directory, 'package.json')))
7
+ airbridge_sdk = JSON.parse(File.read(File.join(current_directory, 'airbridge_sdk.json')))
4
8
 
5
- package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
6
9
  source = Pathname.new(Dir.pwd).relative_path_from(Pathname.new(__dir__)).to_s
7
10
 
8
11
  Pod::Spec.new do |s|
@@ -20,15 +23,15 @@ Pod::Spec.new do |s|
20
23
 
21
24
  s.preserve_paths = 'README.md', 'package.json', 'index.js'
22
25
 
23
- s.source_files = 'ios/AirbridgeRN/*.{h,m}'
26
+ s.source_files = 'ios/AirbridgeReactNative/**/*.{h,m,swift}'
24
27
 
25
- s.header_dir = 'AirbridgeRN'
26
- s.public_header_files = 'ios/AirbridgeRN/AirbridgeRN.h'
28
+ s.header_dir = 'AirbridgeReactNative'
29
+ s.public_header_files = 'ios/AirbridgeReactNative/AirbridgeReactNative.h'
27
30
 
28
31
  s.dependency 'React'
29
- s.dependency 'AirBridgeRestricted', '1.37.3'
32
+ s.dependency 'airbridge-ios-sdk-restricted', airbridge_sdk['ios_version']
30
33
 
31
34
  s.pod_target_xcconfig = {
32
35
  'DEFINES_MODULE' => 'YES'
33
36
  }
34
- end
37
+ end
@@ -0,0 +1,4 @@
1
+ {
2
+ "ios_version": "4.1.0",
3
+ "android_version": "4.1.0"
4
+ }
@@ -1,17 +1,29 @@
1
+ import groovy.json.JsonSlurper
2
+
1
3
  apply plugin: 'com.android.library'
4
+ apply plugin: 'kotlin-android'
2
5
 
3
6
  buildscript {
4
7
  ext.safeExtGet = { prop, fallback ->
5
8
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
6
9
  }
10
+
11
+ ext.getKotlinVersion = {
12
+ if (ext.has("kotlinVersion")) {
13
+ ext.kotlinVersion()
14
+ } else {
15
+ ext.safeExtGet("kotlinVersion", "1.5.31")
16
+ }
17
+ }
18
+
7
19
  }
8
20
 
9
21
  android {
10
- compileSdkVersion safeExtGet("compileSdkVersion", 30)
22
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
11
23
 
12
24
  defaultConfig {
13
25
  minSdkVersion safeExtGet("minSdkVersion", 16)
14
- targetSdkVersion safeExtGet("targetSdkVersion", 30)
26
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
15
27
  versionCode 1
16
28
  versionName '1.0.0'
17
29
  }
@@ -19,14 +31,19 @@ android {
19
31
 
20
32
  rootProject.allprojects {
21
33
  repositories {
34
+ google()
35
+ mavenCentral()
22
36
  maven { url 'https://sdk-download.airbridge.io/maven' }
23
37
  }
24
38
  }
25
39
 
40
+ def currentDirectory = buildFile.parentFile.toPath()
41
+ def airbridgeSDK = new JsonSlurper().parse(currentDirectory.resolve('../airbridge_sdk.json'))
42
+
26
43
  dependencies {
27
44
  implementation 'com.facebook.react:react-native:+'
28
- api 'io.airbridge:sdk-android-restricted:2.25.0'
29
- implementation 'com.android.installreferrer:installreferrer:2.1'
45
+ implementation "io.airbridge:sdk-android-restricted:${airbridgeSDK['android_version']}"
46
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
30
47
  }
31
48
 
32
- apply from: 'copy-config.gradle'
49
+ apply from: 'copy-airbridge-json.gradle'
@@ -1,4 +1,4 @@
1
- def processConfgJSON = {
1
+ def processAirbridgeJSON = {
2
2
  def content = '{}'.getBytes()
3
3
 
4
4
  def json = rootProject.file('../airbridge.json')
@@ -15,4 +15,4 @@ def processConfgJSON = {
15
15
  file.write(new String(content))
16
16
  }
17
17
 
18
- preBuild.dependsOn processConfgJSON
18
+ preBuild.dependsOn processAirbridgeJSON
@@ -0,0 +1,141 @@
1
+ package co.ab180.airbridge.reactnative
2
+
3
+ import android.app.Application
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.util.Log
7
+ import android.view.View
8
+ import co.ab180.airbridge.Airbridge
9
+ import co.ab180.airbridge.AirbridgeOptionBuilder
10
+ import co.ab180.airbridge.reactnative.common.AirbridgeLifecycleIntegration
11
+ import co.ab180.airbridge.reactnative.extension.setAirbridgeJSON
12
+ import co.ab180.airbridge.reactnative.extension.toMap
13
+ import co.ab180.airbridge.reactnative.module.AttributionInteractor
14
+ import co.ab180.airbridge.reactnative.module.DeeplinkInteractor
15
+ import co.ab180.airbridge.reactnative.module.EventInteractor
16
+ import co.ab180.airbridge.reactnative.module.FetchInteractor
17
+ import co.ab180.airbridge.reactnative.module.PlacementInteractor
18
+ import co.ab180.airbridge.reactnative.module.RegisterInteractor
19
+ import co.ab180.airbridge.reactnative.module.SwitchInteractor
20
+ import co.ab180.airbridge.reactnative.module.WebInterfaceInteractor
21
+ import com.facebook.react.ReactPackage
22
+ import com.facebook.react.bridge.NativeModule
23
+ import com.facebook.react.bridge.ReactApplicationContext
24
+ import com.facebook.react.uimanager.ReactShadowNode
25
+ import com.facebook.react.uimanager.ViewManager
26
+ import org.json.JSONException
27
+ import org.json.JSONObject
28
+ import java.io.IOException
29
+
30
+ class AirbridgeReactNative : ReactPackage {
31
+ companion object {
32
+ private var lifecycleIntegration: AirbridgeLifecycleIntegration? = null
33
+
34
+ /**
35
+ * Initialize Airbridge SDK.
36
+ *
37
+ * You should call this method on MainApplication#onCreate.
38
+ * @param app Context from MainApplication#onCreate
39
+ * @param name App Name in English
40
+ * @param token App Token
41
+ */
42
+ @JvmStatic
43
+ fun initializeSDK(
44
+ app: Application,
45
+ name: String,
46
+ token: String,
47
+ ) {
48
+ initializeSDK(app, name, token, loadAirbridgeJSON(app)?.toMap())
49
+ }
50
+
51
+ @JvmStatic
52
+ private fun initializeSDK(
53
+ app: Application,
54
+ name: String,
55
+ token: String,
56
+ airbridgeJSON: Map<String, Any>?
57
+ ) {
58
+ Airbridge.initializeSDK(
59
+ app,
60
+ AirbridgeOptionBuilder(name, token)
61
+ .setAirbridgeJSON(airbridgeJSON)
62
+ .setSDKDevelopmentPlatform("react_native")
63
+ .setOnAttributionReceived {
64
+ AttributionInteractor.onAttributionReceived(it)
65
+ }
66
+ .setLifecycleIntegration {
67
+ lifecycleIntegration?.getDataString(it)
68
+ }
69
+ .build()
70
+ )
71
+ Airbridge.handleDeferredDeeplink(
72
+ onSuccess = { it?.also { DeeplinkInteractor.onDeeplinkReceived(it) } },
73
+ onFailure = { Log.d("AirbridgeReactNative", "Failure on Airbridge.handleDeferredDeeplink: error={${it.localizedMessage}}") }
74
+ )
75
+ }
76
+
77
+ /**
78
+ * Tracks app behavior through deeplink.
79
+ *
80
+ * You should call this method on MainActivity#onResume.
81
+ * @param intent intent from MainActivity#onResume
82
+ */
83
+ @JvmStatic
84
+ fun trackDeeplink(intent: Intent) {
85
+ val handled = Airbridge.handleDeeplink(
86
+ intent = intent,
87
+ onSuccess = { DeeplinkInteractor.onDeeplinkReceived(it) },
88
+ onFailure = { Log.d("AirbridgeReactNative", "Failure on Airbridge.handleDeeplink: error={${it.localizedMessage}}") }
89
+ )
90
+ if (handled) { return }
91
+ intent.data?.also {
92
+ DeeplinkInteractor.onDeeplinkReceived(it)
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Use this method to fetch the correct deep links in exceptional circumstances.
98
+ *
99
+ * When your app is opened by tapping a push notification,
100
+ * third-party libraries (like `Braze`) can provide a customized mechanism to handle deep links.
101
+ * This mechanism may differ from the default Android OS deeplinking process.
102
+ *
103
+ * @param lifecycleIntegration An instance of [AirbridgeLifecycleIntegration] that defines the customized mechanism for handling deeplinks.
104
+ */
105
+ @JvmStatic
106
+ fun setLifecycleIntegration(lifecycleIntegration: AirbridgeLifecycleIntegration) {
107
+ AirbridgeReactNative.lifecycleIntegration = lifecycleIntegration
108
+ }
109
+ }
110
+
111
+ override fun createNativeModules(
112
+ reactContext: ReactApplicationContext
113
+ ): List<NativeModule> =
114
+ listOf(
115
+ EventInteractor(reactContext),
116
+ DeeplinkInteractor(reactContext),
117
+ RegisterInteractor(reactContext),
118
+ PlacementInteractor(reactContext),
119
+ AttributionInteractor(reactContext),
120
+ FetchInteractor(reactContext),
121
+ SwitchInteractor(reactContext),
122
+ WebInterfaceInteractor(reactContext)
123
+ )
124
+
125
+ override fun createViewManagers(
126
+ reactContext: ReactApplicationContext
127
+ ): List<ViewManager<View, ReactShadowNode<*>>> = emptyList()
128
+ }
129
+
130
+ private fun loadAirbridgeJSON(context: Context): JSONObject? {
131
+ try {
132
+ return JSONObject(context.assets.open("airbridge.json").reader().readText())
133
+ } catch (ignored: IOException) {
134
+ // when do not use airbridge.json file
135
+ } catch (exception: JSONException) {
136
+ Log.w("AirbridgeReactNative", "File airbridge.json is not in json format")
137
+ } catch (throwable: Throwable) {
138
+ // unknown exception
139
+ }
140
+ return null
141
+ }
@@ -0,0 +1,7 @@
1
+ package co.ab180.airbridge.reactnative.common
2
+
3
+ import android.app.Activity
4
+
5
+ interface AirbridgeLifecycleIntegration {
6
+ fun getDataString(activity: Activity): String?
7
+ }
@@ -0,0 +1,79 @@
1
+ package co.ab180.airbridge.reactnative.extension
2
+
3
+ import co.ab180.airbridge.AirbridgeLogLevel
4
+ import co.ab180.airbridge.AirbridgeOptionBuilder
5
+
6
+ internal fun AirbridgeOptionBuilder.setAirbridgeJSON(
7
+ airbridgeJSON: Map<String, Any>?
8
+ ): AirbridgeOptionBuilder {
9
+ val json = airbridgeJSON ?: return this
10
+
11
+ (json["sdkEnabled"] as? Boolean)?.also {
12
+ setSDKEnabled(it)
13
+ }
14
+ (json["logLevel"] as? String)?.also {
15
+ when (it) {
16
+ "debug" -> setLogLevel(AirbridgeLogLevel.DEBUG)
17
+ "info" -> setLogLevel(AirbridgeLogLevel.INFO)
18
+ "warning" -> setLogLevel(AirbridgeLogLevel.WARNING)
19
+ "error" -> setLogLevel(AirbridgeLogLevel.ERROR)
20
+ "fault" -> setLogLevel(AirbridgeLogLevel.FAULT)
21
+ else -> {}
22
+ }
23
+ }
24
+ (json["autoStartTrackingEnabled"] as? Boolean)?.also {
25
+ setAutoStartTrackingEnabled(it)
26
+ }
27
+ (json["trackingLinkCustomDomains"] as? List<*>)?.also { array ->
28
+ setCustomDomains(array.mapNotNull { it as? String })
29
+ }
30
+ (json["trackMetaDeferredAppLinkEnabled"] as? Boolean)?.also {
31
+ setTrackMetaDeferredAppLinkEnabled(it)
32
+ }
33
+ (json["sessionTimeoutInSecond"] as? Number)?.also {
34
+ setSessionTimeout(it.toLong())
35
+ }
36
+ (json["appStoreName"] as? String)?.also {
37
+ setAppMarketIdentifier(it)
38
+ }
39
+ (json["collectLocationEnabled"] as? Boolean)?.also {
40
+ setCollectLocationEnabled(it)
41
+ }
42
+ (json["metaInstallReferrerAppID"] as? String)?.also {
43
+ setMetaInstallReferrer(it)
44
+ }
45
+ (json["trackAirbridgeDeeplinkOnlyEnabled"] as? Boolean)?.also {
46
+ setTrackAirbridgeDeeplinkOnlyEnabled(it)
47
+ }
48
+ (json["trackInSessionLifecycleEventEnabled"] as? Boolean)?.also {
49
+ setTrackInSessionLifeCycleEventEnabled(it)
50
+ }
51
+ (json["hashUserInformationEnabled"] as? Boolean)?.also {
52
+ setHashUserInformationEnabled(it)
53
+ }
54
+ (json["sdkSignatureID"] as? String)?.also { id ->
55
+ (json["sdkSignatureSecret"] as? String)?.also { secret ->
56
+ setSDKSignature(id, secret)
57
+ }
58
+ }
59
+ (json["clearEventBufferOnInitializeEnabled"] as? Boolean)?.also {
60
+ setClearEventBufferOnInitializeEnabled(it)
61
+ }
62
+ (json["eventBufferCountLimit"] as? Number)?.also {
63
+ setEventBufferCountLimit(it.toInt())
64
+ }
65
+ (json["eventBufferSizeLimitInGibibyte"] as? Number)?.also {
66
+ setEventBufferSizeLimit(it.toDouble())
67
+ }
68
+ (json["pauseEventTransmitOnBackgroundEnabled"] as? Boolean)?.also {
69
+ setPauseEventTransmitOnBackgroundEnabled(it)
70
+ }
71
+ (json["eventTransmitIntervalInSecond"] as? Number)?.also {
72
+ setEventTransmitInterval(it.toLong())
73
+ }
74
+ (json["errorLogCollectionEnabled"] as? Boolean)?.also {
75
+ setErrorLogCollectionEnabled(it)
76
+ }
77
+
78
+ return this
79
+ }
@@ -0,0 +1,33 @@
1
+ package co.ab180.airbridge.reactnative.extension
2
+
3
+ import org.json.JSONArray
4
+ import org.json.JSONObject
5
+ import java.util.LinkedList
6
+
7
+ internal fun JSONObject.toMap(): Map<String, Any> {
8
+ val map = HashMap<String, Any>()
9
+ for (key in keys()) {
10
+ opt(key)?.also {
11
+ when (it) {
12
+ is JSONObject -> { map[key] = it.toMap() }
13
+ is JSONArray -> { map[key] = it.toList() }
14
+ else -> { map[key] = it }
15
+ }
16
+ }
17
+ }
18
+ return map
19
+ }
20
+
21
+ internal fun JSONArray.toList(): List<Any> {
22
+ val list = LinkedList<Any>()
23
+ for (index in 0..<length()) {
24
+ opt(index)?.also {
25
+ when (it) {
26
+ is JSONObject -> { list[index] = it.toMap() }
27
+ is JSONArray -> { list[index] = it.toList() }
28
+ else -> { list[index] = it }
29
+ }
30
+ }
31
+ }
32
+ return list
33
+ }
@@ -0,0 +1,54 @@
1
+ package co.ab180.airbridge.reactnative.module
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactContext
5
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
6
+ import com.facebook.react.bridge.ReactMethod
7
+ import com.facebook.react.bridge.ReadableMap
8
+ import com.facebook.react.bridge.WritableNativeMap
9
+ import java.lang.ref.WeakReference
10
+
11
+ internal class AttributionInteractor(
12
+ reactContext: ReactApplicationContext?
13
+ ) : ReactContextBaseJavaModule(reactContext) {
14
+ companion object {
15
+ private var initialAttribution: Map<String, String>? = null
16
+ internal var onAttributionReceived: (Map<String, String>) -> Unit = {
17
+ initialAttribution = it
18
+ }
19
+ }
20
+
21
+ override fun getName(): String = "AttributionInteractor"
22
+
23
+ @ReactMethod
24
+ fun listen() {
25
+ val weakThis = WeakReference(this)
26
+
27
+ if (initialAttribution != null) {
28
+ weakThis.get()?.reactApplicationContext
29
+ ?.getJSModule(ReactContext.RCTDeviceEventEmitter::class.java)
30
+ ?.emit("airbridge.attribution", initialAttribution?.toReadableMap())
31
+ initialAttribution = null
32
+ }
33
+
34
+ onAttributionReceived = { attribution ->
35
+ weakThis.get()?.reactApplicationContext
36
+ ?.getJSModule(ReactContext.RCTDeviceEventEmitter::class.java)
37
+ ?.emit("airbridge.attribution", attribution.toReadableMap())
38
+ }
39
+ }
40
+
41
+ @ReactMethod
42
+ fun addListener(eventName: String) {}
43
+
44
+ @ReactMethod
45
+ fun removeListeners(count: Int) {}
46
+ }
47
+
48
+ private fun Map<String, String>.toReadableMap(): ReadableMap {
49
+ val map = WritableNativeMap()
50
+ for (entry in this.entries) {
51
+ map.putString(entry.key, entry.value)
52
+ }
53
+ return map
54
+ }
@@ -0,0 +1,45 @@
1
+ package co.ab180.airbridge.reactnative.module
2
+
3
+ import android.net.Uri
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactContext
6
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
7
+ import com.facebook.react.bridge.ReactMethod
8
+ import java.lang.ref.WeakReference
9
+
10
+ internal class DeeplinkInteractor(
11
+ reactContext: ReactApplicationContext?
12
+ ) : ReactContextBaseJavaModule(reactContext) {
13
+ companion object {
14
+ private var initialDeeplink: Uri? = null
15
+ internal var onDeeplinkReceived: (Uri) -> Unit = {
16
+ initialDeeplink = it
17
+ }
18
+ }
19
+
20
+ override fun getName(): String = "DeeplinkInteractor"
21
+
22
+ @ReactMethod
23
+ fun listen() {
24
+ val weakThis = WeakReference(this)
25
+
26
+ if (initialDeeplink != null) {
27
+ weakThis.get()?.reactApplicationContext
28
+ ?.getJSModule(ReactContext.RCTDeviceEventEmitter::class.java)
29
+ ?.emit("airbridge.deeplink", initialDeeplink.toString())
30
+ initialDeeplink = null
31
+ }
32
+
33
+ onDeeplinkReceived = { deeplink ->
34
+ weakThis.get()?.reactApplicationContext
35
+ ?.getJSModule(ReactContext.RCTDeviceEventEmitter::class.java)
36
+ ?.emit("airbridge.deeplink", deeplink.toString())
37
+ }
38
+ }
39
+
40
+ @ReactMethod
41
+ fun addListener(eventName: String) {}
42
+
43
+ @ReactMethod
44
+ fun removeListeners(count: Int) {}
45
+ }