akanjs 3.0.0-beta.20 → 3.0.0-beta.21

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 (731) hide show
  1. package/README.ko.md +0 -1
  2. package/README.md +0 -1
  3. package/base/baseEnv.ts +40 -3
  4. package/client/cookie.ts +56 -20
  5. package/client/device.ts +47 -95
  6. package/client/frameConfig.ts +2 -2
  7. package/client/native.ts +44 -0
  8. package/client/router.ts +11 -1
  9. package/client/rscNavigation.ts +5 -0
  10. package/client/storage.ts +68 -39
  11. package/fetch/client/fetchClient.ts +13 -4
  12. package/index.ts +47 -46
  13. package/package.json +6 -87
  14. package/server/devtools/signalSerializer.ts +1 -2
  15. package/server/hmr/devHmrController.ts +29 -11
  16. package/server/resolver/signal.resolver.ts +1 -10
  17. package/server/routeTreeBuilder.ts +8 -11
  18. package/server/routing/apiRouter.ts +15 -2
  19. package/server/rscClient.tsx +1 -2
  20. package/server/ssrFromRscRenderer.tsx +2 -0
  21. package/server/webRouter.ts +1 -0
  22. package/signal/CrossSiteGuard.ts +34 -2
  23. package/signal/endpoint.ts +12 -7
  24. package/signal/endpointInfo.ts +13 -0
  25. package/signal/internal.ts +9 -5
  26. package/signal/serializer/fetch.serializer.ts +6 -3
  27. package/signal/slice.ts +34 -24
  28. package/store/baseSt.ts +0 -1
  29. package/store/storeInstance.ts +29 -17
  30. package/types/client/cookie.d.ts +6 -4
  31. package/types/client/device.d.ts +7 -10
  32. package/types/client/native.d.ts +26 -0
  33. package/types/client/rscNavigation.d.ts +4 -0
  34. package/types/client/storage.d.ts +8 -1
  35. package/types/index.d.ts +48 -44
  36. package/types/server/hmr/devHmrController.d.ts +2 -1
  37. package/types/server/resolver/signal.resolver.d.ts +0 -1
  38. package/types/server/rscClient.d.ts +0 -3
  39. package/types/signal/CrossSiteGuard.d.ts +7 -2
  40. package/types/signal/endpoint.d.ts +1 -1
  41. package/types/signal/endpointInfo.d.ts +3 -0
  42. package/types/signal/slice.d.ts +3 -2
  43. package/types/store/baseSt.d.ts +0 -13
  44. package/types/vendor/@akanjs/native/packages/cli/src/api.d.ts +182 -0
  45. package/types/vendor/@akanjs/native/packages/cli/src/commands/build.d.ts +28 -0
  46. package/types/vendor/@akanjs/native/packages/cli/src/commands/compat.d.ts +2 -0
  47. package/types/vendor/@akanjs/native/packages/cli/src/commands/dev.d.ts +2 -0
  48. package/types/vendor/@akanjs/native/packages/cli/src/commands/doctor.d.ts +37 -0
  49. package/types/vendor/@akanjs/native/packages/cli/src/commands/plugin.d.ts +2 -0
  50. package/types/vendor/@akanjs/native/packages/cli/src/commands/signing.d.ts +2 -0
  51. package/types/vendor/@akanjs/native/packages/cli/src/commands/test.d.ts +2 -0
  52. package/types/vendor/@akanjs/native/packages/cli/src/commands/toolchain.d.ts +2 -0
  53. package/types/vendor/@akanjs/native/packages/cli/src/commands/update.d.ts +2 -0
  54. package/types/vendor/@akanjs/native/packages/cli/src/config.d.ts +278 -0
  55. package/types/vendor/@akanjs/native/packages/cli/src/index.d.ts +2 -0
  56. package/types/vendor/@akanjs/native/packages/cli/src/lib/acl.d.ts +21 -0
  57. package/types/vendor/@akanjs/native/packages/cli/src/lib/apilevel.d.ts +40 -0
  58. package/types/vendor/@akanjs/native/packages/cli/src/lib/apk.d.ts +36 -0
  59. package/types/vendor/@akanjs/native/packages/cli/src/lib/args.d.ts +9 -0
  60. package/types/vendor/@akanjs/native/packages/cli/src/lib/boot.d.ts +32 -0
  61. package/types/vendor/@akanjs/native/packages/cli/src/lib/chrome.d.ts +6 -0
  62. package/types/vendor/@akanjs/native/packages/cli/src/lib/codegen.d.ts +94 -0
  63. package/types/vendor/@akanjs/native/packages/cli/src/lib/compat.d.ts +49 -0
  64. package/types/vendor/@akanjs/native/packages/cli/src/lib/configkeys.d.ts +2 -0
  65. package/types/vendor/@akanjs/native/packages/cli/src/lib/csp.d.ts +51 -0
  66. package/types/vendor/@akanjs/native/packages/cli/src/lib/env.d.ts +44 -0
  67. package/types/vendor/@akanjs/native/packages/cli/src/lib/exec.d.ts +31 -0
  68. package/types/vendor/@akanjs/native/packages/cli/src/lib/googleservices.d.ts +2 -0
  69. package/types/vendor/@akanjs/native/packages/cli/src/lib/hmr.d.ts +120 -0
  70. package/types/vendor/@akanjs/native/packages/cli/src/lib/html.d.ts +20 -0
  71. package/types/vendor/@akanjs/native/packages/cli/src/lib/icons.d.ts +44 -0
  72. package/types/vendor/@akanjs/native/packages/cli/src/lib/image.d.ts +21 -0
  73. package/types/vendor/@akanjs/native/packages/cli/src/lib/iossigning.d.ts +81 -0
  74. package/types/vendor/@akanjs/native/packages/cli/src/lib/launch.d.ts +51 -0
  75. package/types/vendor/@akanjs/native/packages/cli/src/lib/log.d.ts +42 -0
  76. package/types/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.d.ts +18 -0
  77. package/types/vendor/@akanjs/native/packages/cli/src/lib/maven.d.ts +97 -0
  78. package/types/vendor/@akanjs/native/packages/cli/src/lib/names.d.ts +45 -0
  79. package/types/vendor/@akanjs/native/packages/cli/src/lib/native-plugins.d.ts +67 -0
  80. package/types/vendor/@akanjs/native/packages/cli/src/lib/nativeconfig.d.ts +11 -0
  81. package/types/vendor/@akanjs/native/packages/cli/src/lib/permissions.d.ts +10 -0
  82. package/types/vendor/@akanjs/native/packages/cli/src/lib/plist.d.ts +11 -0
  83. package/types/vendor/@akanjs/native/packages/cli/src/lib/png.d.ts +11 -0
  84. package/types/vendor/@akanjs/native/packages/cli/src/lib/prepare.d.ts +138 -0
  85. package/types/vendor/@akanjs/native/packages/cli/src/lib/privacy.d.ts +13 -0
  86. package/types/vendor/@akanjs/native/packages/cli/src/lib/project.d.ts +208 -0
  87. package/types/vendor/@akanjs/native/packages/cli/src/lib/root.d.ts +1 -0
  88. package/types/vendor/@akanjs/native/packages/cli/src/lib/routes.d.ts +1 -0
  89. package/types/vendor/@akanjs/native/packages/cli/src/lib/serve.d.ts +17 -0
  90. package/types/vendor/@akanjs/native/packages/cli/src/lib/signing.d.ts +14 -0
  91. package/types/vendor/@akanjs/native/packages/cli/src/lib/spec.d.ts +96 -0
  92. package/types/vendor/@akanjs/native/packages/cli/src/lib/toolchains.d.ts +150 -0
  93. package/types/vendor/@akanjs/native/packages/cli/src/lib/updates.d.ts +77 -0
  94. package/types/vendor/@akanjs/native/packages/cli/src/lib/vectors.d.ts +13 -0
  95. package/types/vendor/@akanjs/native/packages/cli/src/lib/xml.d.ts +13 -0
  96. package/types/vendor/@akanjs/native/packages/cli/src/platforms/android.d.ts +57 -0
  97. package/types/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.d.ts +4 -0
  98. package/types/vendor/@akanjs/native/packages/cli/src/platforms/desktop.d.ts +40 -0
  99. package/types/vendor/@akanjs/native/packages/cli/src/platforms/index.d.ts +14 -0
  100. package/types/vendor/@akanjs/native/packages/cli/src/platforms/ios.d.ts +44 -0
  101. package/types/vendor/@akanjs/native/packages/cli/src/platforms/linux.d.ts +6 -0
  102. package/types/vendor/@akanjs/native/packages/cli/src/platforms/macos.d.ts +7 -0
  103. package/types/vendor/@akanjs/native/packages/cli/src/platforms/targets.d.ts +4 -0
  104. package/types/vendor/@akanjs/native/packages/cli/src/platforms/web-run.d.ts +15 -0
  105. package/types/vendor/@akanjs/native/packages/cli/src/platforms/web.d.ts +2 -0
  106. package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows.d.ts +8 -0
  107. package/types/vendor/@akanjs/native/packages/cli/src/platforms.d.ts +1 -0
  108. package/types/vendor/@akanjs/native/packages/cli/src.d.ts +1 -0
  109. package/types/vendor/@akanjs/native/packages/core/src/acl.d.ts +97 -0
  110. package/types/vendor/@akanjs/native/packages/core/src/boot.d.ts +66 -0
  111. package/types/vendor/@akanjs/native/packages/core/src/contract.d.ts +35 -0
  112. package/types/vendor/@akanjs/native/packages/core/src/errors.d.ts +27 -0
  113. package/types/vendor/@akanjs/native/packages/core/src/files.d.ts +23 -0
  114. package/types/vendor/@akanjs/native/packages/core/src/index.d.ts +14 -0
  115. package/types/vendor/@akanjs/native/packages/core/src/kernel.d.ts +112 -0
  116. package/types/vendor/@akanjs/native/packages/core/src/live.d.ts +12 -0
  117. package/types/vendor/@akanjs/native/packages/core/src/mime.d.ts +2 -0
  118. package/types/vendor/@akanjs/native/packages/core/src/plugin.d.ts +71 -0
  119. package/types/vendor/@akanjs/native/packages/core/src/protocol.d.ts +109 -0
  120. package/types/vendor/@akanjs/native/packages/core/src/runtime.d.ts +66 -0
  121. package/types/vendor/@akanjs/native/packages/core/src/state.d.ts +28 -0
  122. package/types/vendor/@akanjs/native/packages/core/src/testing.d.ts +41 -0
  123. package/types/vendor/@akanjs/native/packages/core/src/version.d.ts +2 -0
  124. package/types/vendor/@akanjs/native/packages/core/src/veto.d.ts +17 -0
  125. package/types/vendor/@akanjs/native/packages/core/src.d.ts +1 -0
  126. package/types/vendor/@akanjs/native/packages/desktop/src/deeplinks.d.ts +24 -0
  127. package/types/vendor/@akanjs/native/packages/desktop/src/delta.d.ts +2 -0
  128. package/types/vendor/@akanjs/native/packages/desktop/src/dispatcher.d.ts +95 -0
  129. package/types/vendor/@akanjs/native/packages/desktop/src/ffi.d.ts +144 -0
  130. package/types/vendor/@akanjs/native/packages/desktop/src/host.d.ts +11 -0
  131. package/types/vendor/@akanjs/native/packages/desktop/src/lifecycle.d.ts +40 -0
  132. package/types/vendor/@akanjs/native/packages/desktop/src/main.d.ts +4 -0
  133. package/types/vendor/@akanjs/native/packages/desktop/src/page-veto.d.ts +17 -0
  134. package/types/vendor/@akanjs/native/packages/desktop/src/paths.d.ts +25 -0
  135. package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +179 -0
  136. package/types/vendor/@akanjs/native/packages/react/src/index.d.ts +8 -0
  137. package/types/vendor/@akanjs/native/packages/react/src.d.ts +1 -0
  138. package/types/vendor/@akanjs/native/plugins/accessibility/src/announce.d.ts +8 -0
  139. package/types/vendor/@akanjs/native/plugins/accessibility/src/index.d.ts +47 -0
  140. package/types/vendor/@akanjs/native/plugins/accessibility/src/web.d.ts +4 -0
  141. package/types/vendor/@akanjs/native/plugins/accessibility/src.d.ts +1 -0
  142. package/types/vendor/@akanjs/native/plugins/app/src/desktop.d.ts +3 -0
  143. package/types/vendor/@akanjs/native/plugins/app/src/index.d.ts +66 -0
  144. package/types/vendor/@akanjs/native/plugins/app/src/web.d.ts +2 -0
  145. package/types/vendor/@akanjs/native/plugins/app/src.d.ts +1 -0
  146. package/types/vendor/@akanjs/native/plugins/app-state/src/index.d.ts +19 -0
  147. package/types/vendor/@akanjs/native/plugins/app-state/src/web.d.ts +2 -0
  148. package/types/vendor/@akanjs/native/plugins/app-state/src.d.ts +1 -0
  149. package/types/vendor/@akanjs/native/plugins/appearance/src/desktop.d.ts +9 -0
  150. package/types/vendor/@akanjs/native/plugins/appearance/src/index.d.ts +32 -0
  151. package/types/vendor/@akanjs/native/plugins/appearance/src/setting.d.ts +6 -0
  152. package/types/vendor/@akanjs/native/plugins/appearance/src/web.d.ts +3 -0
  153. package/types/vendor/@akanjs/native/plugins/appearance/src.d.ts +1 -0
  154. package/types/vendor/@akanjs/native/plugins/auth-session/src/args.d.ts +18 -0
  155. package/types/vendor/@akanjs/native/plugins/auth-session/src/desktop.d.ts +17 -0
  156. package/types/vendor/@akanjs/native/plugins/auth-session/src/index.d.ts +41 -0
  157. package/types/vendor/@akanjs/native/plugins/auth-session/src.d.ts +1 -0
  158. package/types/vendor/@akanjs/native/plugins/autostart/src/desktop.d.ts +44 -0
  159. package/types/vendor/@akanjs/native/plugins/autostart/src/index.d.ts +44 -0
  160. package/types/vendor/@akanjs/native/plugins/autostart/src.d.ts +1 -0
  161. package/types/vendor/@akanjs/native/plugins/badge/src/count.d.ts +4 -0
  162. package/types/vendor/@akanjs/native/plugins/badge/src/desktop.d.ts +3 -0
  163. package/types/vendor/@akanjs/native/plugins/badge/src/index.d.ts +37 -0
  164. package/types/vendor/@akanjs/native/plugins/badge/src/web.d.ts +2 -0
  165. package/types/vendor/@akanjs/native/plugins/badge/src.d.ts +1 -0
  166. package/types/vendor/@akanjs/native/plugins/biometric/src/index.d.ts +53 -0
  167. package/types/vendor/@akanjs/native/plugins/biometric/src.d.ts +1 -0
  168. package/types/vendor/@akanjs/native/plugins/browser/src/args.d.ts +8 -0
  169. package/types/vendor/@akanjs/native/plugins/browser/src/desktop.d.ts +9 -0
  170. package/types/vendor/@akanjs/native/plugins/browser/src/index.d.ts +36 -0
  171. package/types/vendor/@akanjs/native/plugins/browser/src/web.d.ts +2 -0
  172. package/types/vendor/@akanjs/native/plugins/browser/src.d.ts +1 -0
  173. package/types/vendor/@akanjs/native/plugins/camera/src/desktop.d.ts +5 -0
  174. package/types/vendor/@akanjs/native/plugins/camera/src/index.d.ts +55 -0
  175. package/types/vendor/@akanjs/native/plugins/camera/src/web.d.ts +2 -0
  176. package/types/vendor/@akanjs/native/plugins/camera/src.d.ts +1 -0
  177. package/types/vendor/@akanjs/native/plugins/clipboard/src/desktop.d.ts +8 -0
  178. package/types/vendor/@akanjs/native/plugins/clipboard/src/index.d.ts +40 -0
  179. package/types/vendor/@akanjs/native/plugins/clipboard/src/web.d.ts +2 -0
  180. package/types/vendor/@akanjs/native/plugins/clipboard/src.d.ts +1 -0
  181. package/types/vendor/@akanjs/native/plugins/device/src/desktop.d.ts +33 -0
  182. package/types/vendor/@akanjs/native/plugins/device/src/index.d.ts +55 -0
  183. package/types/vendor/@akanjs/native/plugins/device/src/web.d.ts +22 -0
  184. package/types/vendor/@akanjs/native/plugins/device/src.d.ts +1 -0
  185. package/types/vendor/@akanjs/native/plugins/dialog/src/desktop.d.ts +3 -0
  186. package/types/vendor/@akanjs/native/plugins/dialog/src/index.d.ts +60 -0
  187. package/types/vendor/@akanjs/native/plugins/dialog/src/options.d.ts +29 -0
  188. package/types/vendor/@akanjs/native/plugins/dialog/src/web.d.ts +2 -0
  189. package/types/vendor/@akanjs/native/plugins/dialog/src.d.ts +1 -0
  190. package/types/vendor/@akanjs/native/plugins/dock/src/desktop.d.ts +3 -0
  191. package/types/vendor/@akanjs/native/plugins/dock/src/index.d.ts +46 -0
  192. package/types/vendor/@akanjs/native/plugins/dock/src.d.ts +1 -0
  193. package/types/vendor/@akanjs/native/plugins/file-picker/src/common.d.ts +33 -0
  194. package/types/vendor/@akanjs/native/plugins/file-picker/src/desktop.d.ts +9 -0
  195. package/types/vendor/@akanjs/native/plugins/file-picker/src/index.d.ts +84 -0
  196. package/types/vendor/@akanjs/native/plugins/file-picker/src/web.d.ts +6 -0
  197. package/types/vendor/@akanjs/native/plugins/file-picker/src.d.ts +1 -0
  198. package/types/vendor/@akanjs/native/plugins/filesystem/src/common.d.ts +49 -0
  199. package/types/vendor/@akanjs/native/plugins/filesystem/src/desktop.d.ts +8 -0
  200. package/types/vendor/@akanjs/native/plugins/filesystem/src/index.d.ts +123 -0
  201. package/types/vendor/@akanjs/native/plugins/filesystem/src/web.d.ts +2 -0
  202. package/types/vendor/@akanjs/native/plugins/filesystem/src.d.ts +1 -0
  203. package/types/vendor/@akanjs/native/plugins/geolocation/src/index.d.ts +93 -0
  204. package/types/vendor/@akanjs/native/plugins/geolocation/src/web.d.ts +11 -0
  205. package/types/vendor/@akanjs/native/plugins/geolocation/src.d.ts +1 -0
  206. package/types/vendor/@akanjs/native/plugins/global-shortcut/src/desktop.d.ts +3 -0
  207. package/types/vendor/@akanjs/native/plugins/global-shortcut/src/index.d.ts +52 -0
  208. package/types/vendor/@akanjs/native/plugins/global-shortcut/src.d.ts +1 -0
  209. package/types/vendor/@akanjs/native/plugins/haptics/src/index.d.ts +31 -0
  210. package/types/vendor/@akanjs/native/plugins/haptics/src/web.d.ts +2 -0
  211. package/types/vendor/@akanjs/native/plugins/haptics/src.d.ts +1 -0
  212. package/types/vendor/@akanjs/native/plugins/http/src/common.d.ts +71 -0
  213. package/types/vendor/@akanjs/native/plugins/http/src/desktop.d.ts +5 -0
  214. package/types/vendor/@akanjs/native/plugins/http/src/index.d.ts +104 -0
  215. package/types/vendor/@akanjs/native/plugins/http/src/web.d.ts +2 -0
  216. package/types/vendor/@akanjs/native/plugins/http/src.d.ts +1 -0
  217. package/types/vendor/@akanjs/native/plugins/iap/src/index.d.ts +171 -0
  218. package/types/vendor/@akanjs/native/plugins/iap/src.d.ts +1 -0
  219. package/types/vendor/@akanjs/native/plugins/keep-awake/src/desktop.d.ts +15 -0
  220. package/types/vendor/@akanjs/native/plugins/keep-awake/src/index.d.ts +33 -0
  221. package/types/vendor/@akanjs/native/plugins/keep-awake/src/web.d.ts +2 -0
  222. package/types/vendor/@akanjs/native/plugins/keep-awake/src.d.ts +1 -0
  223. package/types/vendor/@akanjs/native/plugins/keyboard/src/index.d.ts +42 -0
  224. package/types/vendor/@akanjs/native/plugins/keyboard/src/web.d.ts +2 -0
  225. package/types/vendor/@akanjs/native/plugins/keyboard/src.d.ts +1 -0
  226. package/types/vendor/@akanjs/native/plugins/local-notifications/src/desktop.d.ts +29 -0
  227. package/types/vendor/@akanjs/native/plugins/local-notifications/src/index.d.ts +126 -0
  228. package/types/vendor/@akanjs/native/plugins/local-notifications/src/schedule.d.ts +38 -0
  229. package/types/vendor/@akanjs/native/plugins/local-notifications/src/timers.d.ts +25 -0
  230. package/types/vendor/@akanjs/native/plugins/local-notifications/src/web.d.ts +4 -0
  231. package/types/vendor/@akanjs/native/plugins/local-notifications/src.d.ts +1 -0
  232. package/types/vendor/@akanjs/native/plugins/menu/src/desktop.d.ts +3 -0
  233. package/types/vendor/@akanjs/native/plugins/menu/src/index.d.ts +85 -0
  234. package/types/vendor/@akanjs/native/plugins/menu/src.d.ts +1 -0
  235. package/types/vendor/@akanjs/native/plugins/network/src/index.d.ts +22 -0
  236. package/types/vendor/@akanjs/native/plugins/network/src/web.d.ts +3 -0
  237. package/types/vendor/@akanjs/native/plugins/network/src.d.ts +1 -0
  238. package/types/vendor/@akanjs/native/plugins/opener/src/desktop.d.ts +14 -0
  239. package/types/vendor/@akanjs/native/plugins/opener/src/index.d.ts +33 -0
  240. package/types/vendor/@akanjs/native/plugins/opener/src/url.d.ts +16 -0
  241. package/types/vendor/@akanjs/native/plugins/opener/src/web.d.ts +2 -0
  242. package/types/vendor/@akanjs/native/plugins/opener/src.d.ts +1 -0
  243. package/types/vendor/@akanjs/native/plugins/preferences/src/desktop.d.ts +3 -0
  244. package/types/vendor/@akanjs/native/plugins/preferences/src/index.d.ts +26 -0
  245. package/types/vendor/@akanjs/native/plugins/preferences/src/web.d.ts +2 -0
  246. package/types/vendor/@akanjs/native/plugins/preferences/src.d.ts +1 -0
  247. package/types/vendor/@akanjs/native/plugins/push/src/index.d.ts +57 -0
  248. package/types/vendor/@akanjs/native/plugins/push/src.d.ts +1 -0
  249. package/types/vendor/@akanjs/native/plugins/screen/src/desktop.d.ts +3 -0
  250. package/types/vendor/@akanjs/native/plugins/screen/src/index.d.ts +70 -0
  251. package/types/vendor/@akanjs/native/plugins/screen/src/web.d.ts +18 -0
  252. package/types/vendor/@akanjs/native/plugins/screen/src.d.ts +1 -0
  253. package/types/vendor/@akanjs/native/plugins/screen-orientation/src/index.d.ts +32 -0
  254. package/types/vendor/@akanjs/native/plugins/screen-orientation/src/types.d.ts +8 -0
  255. package/types/vendor/@akanjs/native/plugins/screen-orientation/src/web.d.ts +3 -0
  256. package/types/vendor/@akanjs/native/plugins/screen-orientation/src.d.ts +1 -0
  257. package/types/vendor/@akanjs/native/plugins/secure-storage/src/desktop.d.ts +16 -0
  258. package/types/vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts +39 -0
  259. package/types/vendor/@akanjs/native/plugins/secure-storage/src.d.ts +1 -0
  260. package/types/vendor/@akanjs/native/plugins/share/src/index.d.ts +55 -0
  261. package/types/vendor/@akanjs/native/plugins/share/src/options.d.ts +6 -0
  262. package/types/vendor/@akanjs/native/plugins/share/src/web.d.ts +5 -0
  263. package/types/vendor/@akanjs/native/plugins/share/src.d.ts +1 -0
  264. package/types/vendor/@akanjs/native/plugins/single-instance/src/desktop.d.ts +8 -0
  265. package/types/vendor/@akanjs/native/plugins/single-instance/src/index.d.ts +25 -0
  266. package/types/vendor/@akanjs/native/plugins/single-instance/src/socket.d.ts +46 -0
  267. package/types/vendor/@akanjs/native/plugins/single-instance/src.d.ts +1 -0
  268. package/types/vendor/@akanjs/native/plugins/splash-screen/src/index.d.ts +19 -0
  269. package/types/vendor/@akanjs/native/plugins/splash-screen/src/web.d.ts +4 -0
  270. package/types/vendor/@akanjs/native/plugins/splash-screen/src.d.ts +1 -0
  271. package/types/vendor/@akanjs/native/plugins/sqlite/src/common.d.ts +34 -0
  272. package/types/vendor/@akanjs/native/plugins/sqlite/src/desktop.d.ts +6 -0
  273. package/types/vendor/@akanjs/native/plugins/sqlite/src/index.d.ts +115 -0
  274. package/types/vendor/@akanjs/native/plugins/sqlite/src.d.ts +1 -0
  275. package/types/vendor/@akanjs/native/plugins/toast/src/index.d.ts +30 -0
  276. package/types/vendor/@akanjs/native/plugins/toast/src/queue.d.ts +23 -0
  277. package/types/vendor/@akanjs/native/plugins/toast/src/web.d.ts +2 -0
  278. package/types/vendor/@akanjs/native/plugins/toast/src.d.ts +1 -0
  279. package/types/vendor/@akanjs/native/plugins/tray/src/desktop.d.ts +3 -0
  280. package/types/vendor/@akanjs/native/plugins/tray/src/index.d.ts +113 -0
  281. package/types/vendor/@akanjs/native/plugins/tray/src.d.ts +1 -0
  282. package/types/vendor/@akanjs/native/plugins/updates/src/desktop.d.ts +4 -0
  283. package/types/vendor/@akanjs/native/plugins/updates/src/index.d.ts +68 -0
  284. package/types/vendor/@akanjs/native/plugins/updates/src.d.ts +1 -0
  285. package/types/vendor/@akanjs/native/plugins/window/src/desktop.d.ts +6 -0
  286. package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +185 -0
  287. package/types/vendor/@akanjs/native/plugins/window/src/web.d.ts +2 -0
  288. package/types/vendor/@akanjs/native/plugins/window/src.d.ts +1 -0
  289. package/types/vendor/@akanjs/native/plugins/window-state/src/desktop.d.ts +7 -0
  290. package/types/vendor/@akanjs/native/plugins/window-state/src/index.d.ts +33 -0
  291. package/types/vendor/@akanjs/native/plugins/window-state/src/state.d.ts +39 -0
  292. package/types/vendor/@akanjs/native/plugins/window-state/src.d.ts +1 -0
  293. package/types/webkit/index.d.ts +0 -2
  294. package/types/webkit/nativeNavigation.d.ts +25 -0
  295. package/types/webkit/nativePurchase.d.ts +37 -0
  296. package/types/webkit/useCamera.d.ts +13 -15
  297. package/types/webkit/useGeoLocation.d.ts +4 -5
  298. package/types/webkit/usePurchase.d.ts +12 -16
  299. package/ui/Link/Anchor.tsx +2 -5
  300. package/ui/System/Client.tsx +2 -6
  301. package/vendor/@akanjs/native/LICENSE +21 -0
  302. package/vendor/@akanjs/native/README.ko.md +88 -0
  303. package/vendor/@akanjs/native/README.md +93 -0
  304. package/vendor/@akanjs/native/THIRD_PARTY_NOTICES.md +237 -0
  305. package/vendor/@akanjs/native/native/android/maven.lock.json +1751 -0
  306. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeAcl.kt +243 -0
  307. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeActivity.kt +936 -0
  308. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeApplication.kt +189 -0
  309. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeAssetServer.kt +225 -0
  310. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeBridge.kt +444 -0
  311. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeCompat.kt +55 -0
  312. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeContract.kt +99 -0
  313. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeEd25519.kt +100 -0
  314. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeFileProvider.kt +71 -0
  315. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeKernel.kt +324 -0
  316. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativePlugin.kt +361 -0
  317. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeSpec.kt +100 -0
  318. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdates.kt +305 -0
  319. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeVectors.kt +132 -0
  320. package/vendor/@akanjs/native/native/desktop/Cargo.lock +2565 -0
  321. package/vendor/@akanjs/native/native/desktop/Cargo.toml +49 -0
  322. package/vendor/@akanjs/native/native/desktop/build.rs +19 -0
  323. package/vendor/@akanjs/native/native/desktop/rust-toolchain.toml +7 -0
  324. package/vendor/@akanjs/native/native/desktop/src/accelerator.rs +466 -0
  325. package/vendor/@akanjs/native/native/desktop/src/autostart.rs +158 -0
  326. package/vendor/@akanjs/native/native/desktop/src/camera.rs +53 -0
  327. package/vendor/@akanjs/native/native/desktop/src/chrome.rs +710 -0
  328. package/vendor/@akanjs/native/native/desktop/src/contract.rs +105 -0
  329. package/vendor/@akanjs/native/native/desktop/src/devproxy.rs +234 -0
  330. package/vendor/@akanjs/native/native/desktop/src/dialog_args.rs +189 -0
  331. package/vendor/@akanjs/native/native/desktop/src/dock.rs +209 -0
  332. package/vendor/@akanjs/native/native/desktop/src/hotkey.rs +209 -0
  333. package/vendor/@akanjs/native/native/desktop/src/js_panels.rs +125 -0
  334. package/vendor/@akanjs/native/native/desktop/src/json.rs +272 -0
  335. package/vendor/@akanjs/native/native/desktop/src/keychain.rs +151 -0
  336. package/vendor/@akanjs/native/native/desktop/src/lib.rs +2185 -0
  337. package/vendor/@akanjs/native/native/desktop/src/linux/appearance.rs +177 -0
  338. package/vendor/@akanjs/native/native/desktop/src/linux/camera.rs +11 -0
  339. package/vendor/@akanjs/native/native/desktop/src/linux/clipboard.rs +48 -0
  340. package/vendor/@akanjs/native/native/desktop/src/linux/device.rs +9 -0
  341. package/vendor/@akanjs/native/native/desktop/src/linux/dialogs.rs +348 -0
  342. package/vendor/@akanjs/native/native/desktop/src/linux/dock.rs +146 -0
  343. package/vendor/@akanjs/native/native/desktop/src/linux/hotkey.rs +228 -0
  344. package/vendor/@akanjs/native/native/desktop/src/linux/keychain.rs +243 -0
  345. package/vendor/@akanjs/native/native/desktop/src/linux/menu.rs +445 -0
  346. package/vendor/@akanjs/native/native/desktop/src/linux/mod.rs +116 -0
  347. package/vendor/@akanjs/native/native/desktop/src/linux/notify.rs +211 -0
  348. package/vendor/@akanjs/native/native/desktop/src/linux/open.rs +79 -0
  349. package/vendor/@akanjs/native/native/desktop/src/linux/power.rs +155 -0
  350. package/vendor/@akanjs/native/native/desktop/src/linux/screen.rs +158 -0
  351. package/vendor/@akanjs/native/native/desktop/src/linux/tray.rs +604 -0
  352. package/vendor/@akanjs/native/native/desktop/src/menu.rs +517 -0
  353. package/vendor/@akanjs/native/native/desktop/src/navigation.rs +381 -0
  354. package/vendor/@akanjs/native/native/desktop/src/notify.rs +411 -0
  355. package/vendor/@akanjs/native/native/desktop/src/notify_schedule.rs +382 -0
  356. package/vendor/@akanjs/native/native/desktop/src/page_menu.rs +287 -0
  357. package/vendor/@akanjs/native/native/desktop/src/panels.rs +333 -0
  358. package/vendor/@akanjs/native/native/desktop/src/placement.rs +92 -0
  359. package/vendor/@akanjs/native/native/desktop/src/routes.rs +153 -0
  360. package/vendor/@akanjs/native/native/desktop/src/screen.rs +190 -0
  361. package/vendor/@akanjs/native/native/desktop/src/tray.rs +279 -0
  362. package/vendor/@akanjs/native/native/desktop/src/vectors.rs +126 -0
  363. package/vendor/@akanjs/native/native/desktop/src/win/appearance.rs +51 -0
  364. package/vendor/@akanjs/native/native/desktop/src/win/autostart.rs +77 -0
  365. package/vendor/@akanjs/native/native/desktop/src/win/camera.rs +34 -0
  366. package/vendor/@akanjs/native/native/desktop/src/win/clipboard.rs +106 -0
  367. package/vendor/@akanjs/native/native/desktop/src/win/device.rs +80 -0
  368. package/vendor/@akanjs/native/native/desktop/src/win/dialogs.rs +917 -0
  369. package/vendor/@akanjs/native/native/desktop/src/win/dock.rs +228 -0
  370. package/vendor/@akanjs/native/native/desktop/src/win/hotkey.rs +110 -0
  371. package/vendor/@akanjs/native/native/desktop/src/win/keychain.rs +103 -0
  372. package/vendor/@akanjs/native/native/desktop/src/win/menu.rs +500 -0
  373. package/vendor/@akanjs/native/native/desktop/src/win/mod.rs +100 -0
  374. package/vendor/@akanjs/native/native/desktop/src/win/msgwin.rs +86 -0
  375. package/vendor/@akanjs/native/native/desktop/src/win/notify.rs +334 -0
  376. package/vendor/@akanjs/native/native/desktop/src/win/open.rs +127 -0
  377. package/vendor/@akanjs/native/native/desktop/src/win/power.rs +64 -0
  378. package/vendor/@akanjs/native/native/desktop/src/win/registry.rs +87 -0
  379. package/vendor/@akanjs/native/native/desktop/src/win/screen.rs +127 -0
  380. package/vendor/@akanjs/native/native/desktop/src/win/tray.rs +280 -0
  381. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeAcl.swift +241 -0
  382. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeApp.swift +285 -0
  383. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeBridge.swift +407 -0
  384. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeContract.swift +106 -0
  385. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeKernel.swift +317 -0
  386. package/vendor/@akanjs/native/native/ios/Sources/AkanNativePlugin.swift +250 -0
  387. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeSchemeHandler.swift +209 -0
  388. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeShell.swift +161 -0
  389. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeSpec.swift +143 -0
  390. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdates.swift +270 -0
  391. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeVectors.swift +155 -0
  392. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeViewController.swift +371 -0
  393. package/vendor/@akanjs/native/packages/cli/src/api.ts +600 -0
  394. package/vendor/@akanjs/native/packages/cli/src/commands/build.ts +101 -0
  395. package/vendor/@akanjs/native/packages/cli/src/commands/compat.ts +53 -0
  396. package/vendor/@akanjs/native/packages/cli/src/commands/dev.ts +249 -0
  397. package/vendor/@akanjs/native/packages/cli/src/commands/doctor.ts +536 -0
  398. package/vendor/@akanjs/native/packages/cli/src/commands/plugin.ts +164 -0
  399. package/vendor/@akanjs/native/packages/cli/src/commands/signing.ts +32 -0
  400. package/vendor/@akanjs/native/packages/cli/src/commands/test.ts +130 -0
  401. package/vendor/@akanjs/native/packages/cli/src/commands/toolchain.ts +143 -0
  402. package/vendor/@akanjs/native/packages/cli/src/commands/update.ts +168 -0
  403. package/vendor/@akanjs/native/packages/cli/src/config.ts +257 -0
  404. package/vendor/@akanjs/native/packages/cli/src/index.ts +77 -0
  405. package/vendor/@akanjs/native/packages/cli/src/lib/acl.ts +420 -0
  406. package/vendor/@akanjs/native/packages/cli/src/lib/apilevel.ts +245 -0
  407. package/vendor/@akanjs/native/packages/cli/src/lib/apk.ts +203 -0
  408. package/vendor/@akanjs/native/packages/cli/src/lib/args.ts +44 -0
  409. package/vendor/@akanjs/native/packages/cli/src/lib/boot.ts +73 -0
  410. package/vendor/@akanjs/native/packages/cli/src/lib/chrome.ts +89 -0
  411. package/vendor/@akanjs/native/packages/cli/src/lib/codegen.ts +1128 -0
  412. package/vendor/@akanjs/native/packages/cli/src/lib/compat.ts +185 -0
  413. package/vendor/@akanjs/native/packages/cli/src/lib/configkeys.ts +91 -0
  414. package/vendor/@akanjs/native/packages/cli/src/lib/csp.ts +198 -0
  415. package/vendor/@akanjs/native/packages/cli/src/lib/env.ts +257 -0
  416. package/vendor/@akanjs/native/packages/cli/src/lib/exec.ts +104 -0
  417. package/vendor/@akanjs/native/packages/cli/src/lib/googleservices.ts +53 -0
  418. package/vendor/@akanjs/native/packages/cli/src/lib/hmr.ts +534 -0
  419. package/vendor/@akanjs/native/packages/cli/src/lib/html.ts +63 -0
  420. package/vendor/@akanjs/native/packages/cli/src/lib/icons.ts +316 -0
  421. package/vendor/@akanjs/native/packages/cli/src/lib/image.ts +175 -0
  422. package/vendor/@akanjs/native/packages/cli/src/lib/iossigning.ts +295 -0
  423. package/vendor/@akanjs/native/packages/cli/src/lib/launch.ts +98 -0
  424. package/vendor/@akanjs/native/packages/cli/src/lib/log.ts +105 -0
  425. package/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.ts +107 -0
  426. package/vendor/@akanjs/native/packages/cli/src/lib/maven.ts +244 -0
  427. package/vendor/@akanjs/native/packages/cli/src/lib/names.ts +202 -0
  428. package/vendor/@akanjs/native/packages/cli/src/lib/native-plugins.ts +326 -0
  429. package/vendor/@akanjs/native/packages/cli/src/lib/nativeconfig.ts +68 -0
  430. package/vendor/@akanjs/native/packages/cli/src/lib/permissions.ts +80 -0
  431. package/vendor/@akanjs/native/packages/cli/src/lib/plist.ts +139 -0
  432. package/vendor/@akanjs/native/packages/cli/src/lib/png.ts +240 -0
  433. package/vendor/@akanjs/native/packages/cli/src/lib/prepare.ts +290 -0
  434. package/vendor/@akanjs/native/packages/cli/src/lib/privacy.ts +64 -0
  435. package/vendor/@akanjs/native/packages/cli/src/lib/project.ts +710 -0
  436. package/vendor/@akanjs/native/packages/cli/src/lib/root.ts +18 -0
  437. package/vendor/@akanjs/native/packages/cli/src/lib/routes.ts +3 -0
  438. package/vendor/@akanjs/native/packages/cli/src/lib/serve.ts +83 -0
  439. package/vendor/@akanjs/native/packages/cli/src/lib/signing.ts +117 -0
  440. package/vendor/@akanjs/native/packages/cli/src/lib/spec.ts +521 -0
  441. package/vendor/@akanjs/native/packages/cli/src/lib/toolchains.ts +579 -0
  442. package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +160 -0
  443. package/vendor/@akanjs/native/packages/cli/src/lib/vectors.ts +121 -0
  444. package/vendor/@akanjs/native/packages/cli/src/lib/xml.ts +72 -0
  445. package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +1320 -0
  446. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.ts +78 -0
  447. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop.ts +279 -0
  448. package/vendor/@akanjs/native/packages/cli/src/platforms/index.ts +31 -0
  449. package/vendor/@akanjs/native/packages/cli/src/platforms/ios.ts +801 -0
  450. package/vendor/@akanjs/native/packages/cli/src/platforms/linux.ts +52 -0
  451. package/vendor/@akanjs/native/packages/cli/src/platforms/macos.ts +97 -0
  452. package/vendor/@akanjs/native/packages/cli/src/platforms/targets.ts +12 -0
  453. package/vendor/@akanjs/native/packages/cli/src/platforms/web-run.ts +69 -0
  454. package/vendor/@akanjs/native/packages/cli/src/platforms/web.ts +28 -0
  455. package/vendor/@akanjs/native/packages/cli/src/platforms/windows.ts +82 -0
  456. package/vendor/@akanjs/native/packages/core/contract.json +96 -0
  457. package/vendor/@akanjs/native/packages/core/src/acl.ts +272 -0
  458. package/vendor/@akanjs/native/packages/core/src/boot.ts +97 -0
  459. package/vendor/@akanjs/native/packages/core/src/contract.ts +100 -0
  460. package/vendor/@akanjs/native/packages/core/src/errors.ts +95 -0
  461. package/vendor/@akanjs/native/packages/core/src/files.ts +105 -0
  462. package/vendor/@akanjs/native/packages/core/src/index.ts +35 -0
  463. package/vendor/@akanjs/native/packages/core/src/kernel.ts +281 -0
  464. package/vendor/@akanjs/native/packages/core/src/live.ts +62 -0
  465. package/vendor/@akanjs/native/packages/core/src/mime.ts +8 -0
  466. package/vendor/@akanjs/native/packages/core/src/plugin.ts +358 -0
  467. package/vendor/@akanjs/native/packages/core/src/protocol.ts +194 -0
  468. package/vendor/@akanjs/native/packages/core/src/runtime.ts +520 -0
  469. package/vendor/@akanjs/native/packages/core/src/state.ts +46 -0
  470. package/vendor/@akanjs/native/packages/core/src/testing.ts +176 -0
  471. package/vendor/@akanjs/native/packages/core/src/version.ts +2 -0
  472. package/vendor/@akanjs/native/packages/core/src/veto.ts +55 -0
  473. package/vendor/@akanjs/native/packages/core/vectors/acl.json +57 -0
  474. package/vendor/@akanjs/native/packages/core/vectors/bridge.json +76 -0
  475. package/vendor/@akanjs/native/packages/core/vectors/ed25519.json +29 -0
  476. package/vendor/@akanjs/native/packages/core/vectors/ids.json +73 -0
  477. package/vendor/@akanjs/native/packages/core/vectors/navigation.json +75 -0
  478. package/vendor/@akanjs/native/packages/core/vectors/ranges.json +39 -0
  479. package/vendor/@akanjs/native/packages/core/vectors/retained.json +17 -0
  480. package/vendor/@akanjs/native/packages/core/vectors/routes.json +66 -0
  481. package/vendor/@akanjs/native/packages/core/vectors/scope.json +143 -0
  482. package/vendor/@akanjs/native/packages/desktop/src/deeplinks.ts +143 -0
  483. package/vendor/@akanjs/native/packages/desktop/src/delta.ts +174 -0
  484. package/vendor/@akanjs/native/packages/desktop/src/dispatcher.ts +679 -0
  485. package/vendor/@akanjs/native/packages/desktop/src/ffi.ts +76 -0
  486. package/vendor/@akanjs/native/packages/desktop/src/host.ts +355 -0
  487. package/vendor/@akanjs/native/packages/desktop/src/lifecycle.ts +142 -0
  488. package/vendor/@akanjs/native/packages/desktop/src/main.ts +133 -0
  489. package/vendor/@akanjs/native/packages/desktop/src/page-veto.ts +103 -0
  490. package/vendor/@akanjs/native/packages/desktop/src/paths.ts +59 -0
  491. package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +232 -0
  492. package/vendor/@akanjs/native/packages/react/src/index.ts +23 -0
  493. package/vendor/@akanjs/native/plugins/accessibility/android/AccessibilityPlugin.kt +96 -0
  494. package/vendor/@akanjs/native/plugins/accessibility/ios/AccessibilityPlugin.swift +92 -0
  495. package/vendor/@akanjs/native/plugins/accessibility/native-plugin.json +21 -0
  496. package/vendor/@akanjs/native/plugins/accessibility/src/announce.ts +71 -0
  497. package/vendor/@akanjs/native/plugins/accessibility/src/index.ts +77 -0
  498. package/vendor/@akanjs/native/plugins/accessibility/src/web.ts +52 -0
  499. package/vendor/@akanjs/native/plugins/app/android/AppPlugin.kt +72 -0
  500. package/vendor/@akanjs/native/plugins/app/ios/AppPlugin.swift +52 -0
  501. package/vendor/@akanjs/native/plugins/app/native-plugin.json +21 -0
  502. package/vendor/@akanjs/native/plugins/app/src/desktop.ts +64 -0
  503. package/vendor/@akanjs/native/plugins/app/src/index.ts +77 -0
  504. package/vendor/@akanjs/native/plugins/app/src/web.ts +12 -0
  505. package/vendor/@akanjs/native/plugins/app-state/android/AppStatePlugin.kt +54 -0
  506. package/vendor/@akanjs/native/plugins/app-state/ios/AppStatePlugin.swift +58 -0
  507. package/vendor/@akanjs/native/plugins/app-state/native-plugin.json +17 -0
  508. package/vendor/@akanjs/native/plugins/app-state/src/index.ts +42 -0
  509. package/vendor/@akanjs/native/plugins/app-state/src/web.ts +33 -0
  510. package/vendor/@akanjs/native/plugins/appearance/android/AppearancePlugin.kt +133 -0
  511. package/vendor/@akanjs/native/plugins/appearance/ios/AppearancePlugin.swift +109 -0
  512. package/vendor/@akanjs/native/plugins/appearance/native-plugin.json +18 -0
  513. package/vendor/@akanjs/native/plugins/appearance/src/desktop.ts +133 -0
  514. package/vendor/@akanjs/native/plugins/appearance/src/index.ts +62 -0
  515. package/vendor/@akanjs/native/plugins/appearance/src/setting.ts +18 -0
  516. package/vendor/@akanjs/native/plugins/appearance/src/web.ts +25 -0
  517. package/vendor/@akanjs/native/plugins/auth-session/android/AuthSessionPlugin.kt +171 -0
  518. package/vendor/@akanjs/native/plugins/auth-session/ios/AuthSessionPlugin.swift +112 -0
  519. package/vendor/@akanjs/native/plugins/auth-session/native-plugin.json +19 -0
  520. package/vendor/@akanjs/native/plugins/auth-session/src/args.ts +62 -0
  521. package/vendor/@akanjs/native/plugins/auth-session/src/desktop.ts +133 -0
  522. package/vendor/@akanjs/native/plugins/auth-session/src/index.ts +39 -0
  523. package/vendor/@akanjs/native/plugins/autostart/native-plugin.json +10 -0
  524. package/vendor/@akanjs/native/plugins/autostart/src/desktop.ts +189 -0
  525. package/vendor/@akanjs/native/plugins/autostart/src/index.ts +51 -0
  526. package/vendor/@akanjs/native/plugins/badge/ios/BadgePlugin.swift +92 -0
  527. package/vendor/@akanjs/native/plugins/badge/native-plugin.json +15 -0
  528. package/vendor/@akanjs/native/plugins/badge/src/count.ts +12 -0
  529. package/vendor/@akanjs/native/plugins/badge/src/desktop.ts +24 -0
  530. package/vendor/@akanjs/native/plugins/badge/src/index.ts +40 -0
  531. package/vendor/@akanjs/native/plugins/badge/src/web.ts +37 -0
  532. package/vendor/@akanjs/native/plugins/biometric/android/BiometricPlugin.kt +179 -0
  533. package/vendor/@akanjs/native/plugins/biometric/ios/BiometricPlugin.swift +129 -0
  534. package/vendor/@akanjs/native/plugins/biometric/native-plugin.json +22 -0
  535. package/vendor/@akanjs/native/plugins/biometric/src/index.ts +100 -0
  536. package/vendor/@akanjs/native/plugins/browser/android/BrowserPlugin.kt +178 -0
  537. package/vendor/@akanjs/native/plugins/browser/ios/BrowserPlugin.swift +63 -0
  538. package/vendor/@akanjs/native/plugins/browser/native-plugin.json +22 -0
  539. package/vendor/@akanjs/native/plugins/browser/src/args.ts +34 -0
  540. package/vendor/@akanjs/native/plugins/browser/src/desktop.ts +40 -0
  541. package/vendor/@akanjs/native/plugins/browser/src/index.ts +47 -0
  542. package/vendor/@akanjs/native/plugins/browser/src/web.ts +60 -0
  543. package/vendor/@akanjs/native/plugins/camera/android/CameraPlugin.kt +365 -0
  544. package/vendor/@akanjs/native/plugins/camera/ios/CameraPlugin.swift +296 -0
  545. package/vendor/@akanjs/native/plugins/camera/native-plugin.json +32 -0
  546. package/vendor/@akanjs/native/plugins/camera/src/desktop.ts +27 -0
  547. package/vendor/@akanjs/native/plugins/camera/src/index.ts +85 -0
  548. package/vendor/@akanjs/native/plugins/camera/src/web.ts +267 -0
  549. package/vendor/@akanjs/native/plugins/clipboard/android/ClipboardPlugin.kt +51 -0
  550. package/vendor/@akanjs/native/plugins/clipboard/ios/ClipboardPlugin.swift +35 -0
  551. package/vendor/@akanjs/native/plugins/clipboard/native-plugin.json +17 -0
  552. package/vendor/@akanjs/native/plugins/clipboard/src/desktop.ts +66 -0
  553. package/vendor/@akanjs/native/plugins/clipboard/src/index.ts +72 -0
  554. package/vendor/@akanjs/native/plugins/clipboard/src/web.ts +69 -0
  555. package/vendor/@akanjs/native/plugins/device/android/DevicePlugin.kt +70 -0
  556. package/vendor/@akanjs/native/plugins/device/ios/DevicePlugin.swift +80 -0
  557. package/vendor/@akanjs/native/plugins/device/native-plugin.json +18 -0
  558. package/vendor/@akanjs/native/plugins/device/src/desktop.ts +276 -0
  559. package/vendor/@akanjs/native/plugins/device/src/index.ts +72 -0
  560. package/vendor/@akanjs/native/plugins/device/src/web.ts +162 -0
  561. package/vendor/@akanjs/native/plugins/dialog/android/DialogPlugin.kt +260 -0
  562. package/vendor/@akanjs/native/plugins/dialog/ios/DialogPlugin.swift +198 -0
  563. package/vendor/@akanjs/native/plugins/dialog/native-plugin.json +18 -0
  564. package/vendor/@akanjs/native/plugins/dialog/src/desktop.ts +80 -0
  565. package/vendor/@akanjs/native/plugins/dialog/src/index.ts +87 -0
  566. package/vendor/@akanjs/native/plugins/dialog/src/options.ts +111 -0
  567. package/vendor/@akanjs/native/plugins/dialog/src/web.ts +296 -0
  568. package/vendor/@akanjs/native/plugins/dock/native-plugin.json +10 -0
  569. package/vendor/@akanjs/native/plugins/dock/src/desktop.ts +34 -0
  570. package/vendor/@akanjs/native/plugins/dock/src/index.ts +46 -0
  571. package/vendor/@akanjs/native/plugins/file-picker/android/FilePickerPlugin.kt +316 -0
  572. package/vendor/@akanjs/native/plugins/file-picker/ios/FilePickerPlugin.swift +366 -0
  573. package/vendor/@akanjs/native/plugins/file-picker/native-plugin.json +18 -0
  574. package/vendor/@akanjs/native/plugins/file-picker/src/common.ts +125 -0
  575. package/vendor/@akanjs/native/plugins/file-picker/src/desktop.ts +164 -0
  576. package/vendor/@akanjs/native/plugins/file-picker/src/index.ts +187 -0
  577. package/vendor/@akanjs/native/plugins/file-picker/src/web.ts +158 -0
  578. package/vendor/@akanjs/native/plugins/filesystem/android/FilesystemPlugin.kt +561 -0
  579. package/vendor/@akanjs/native/plugins/filesystem/ios/FilesystemPlugin.swift +596 -0
  580. package/vendor/@akanjs/native/plugins/filesystem/native-plugin.json +45 -0
  581. package/vendor/@akanjs/native/plugins/filesystem/src/common.ts +150 -0
  582. package/vendor/@akanjs/native/plugins/filesystem/src/desktop.ts +438 -0
  583. package/vendor/@akanjs/native/plugins/filesystem/src/index.ts +179 -0
  584. package/vendor/@akanjs/native/plugins/filesystem/src/web.ts +334 -0
  585. package/vendor/@akanjs/native/plugins/geolocation/android/GeolocationPlugin.kt +360 -0
  586. package/vendor/@akanjs/native/plugins/geolocation/ios/GeolocationPlugin.swift +284 -0
  587. package/vendor/@akanjs/native/plugins/geolocation/native-plugin.json +23 -0
  588. package/vendor/@akanjs/native/plugins/geolocation/src/index.ts +155 -0
  589. package/vendor/@akanjs/native/plugins/geolocation/src/web.ts +132 -0
  590. package/vendor/@akanjs/native/plugins/global-shortcut/native-plugin.json +10 -0
  591. package/vendor/@akanjs/native/plugins/global-shortcut/src/desktop.ts +36 -0
  592. package/vendor/@akanjs/native/plugins/global-shortcut/src/index.ts +55 -0
  593. package/vendor/@akanjs/native/plugins/haptics/android/HapticsPlugin.kt +127 -0
  594. package/vendor/@akanjs/native/plugins/haptics/ios/HapticsPlugin.swift +127 -0
  595. package/vendor/@akanjs/native/plugins/haptics/native-plugin.json +19 -0
  596. package/vendor/@akanjs/native/plugins/haptics/src/index.ts +34 -0
  597. package/vendor/@akanjs/native/plugins/haptics/src/web.ts +53 -0
  598. package/vendor/@akanjs/native/plugins/http/android/HttpPlugin.kt +234 -0
  599. package/vendor/@akanjs/native/plugins/http/android/HttpUrl.kt +182 -0
  600. package/vendor/@akanjs/native/plugins/http/ios/HttpPlugin.swift +228 -0
  601. package/vendor/@akanjs/native/plugins/http/ios/HttpUrl.swift +166 -0
  602. package/vendor/@akanjs/native/plugins/http/native-plugin.json +27 -0
  603. package/vendor/@akanjs/native/plugins/http/src/common.ts +294 -0
  604. package/vendor/@akanjs/native/plugins/http/src/desktop.ts +69 -0
  605. package/vendor/@akanjs/native/plugins/http/src/index.ts +181 -0
  606. package/vendor/@akanjs/native/plugins/http/src/web.ts +40 -0
  607. package/vendor/@akanjs/native/plugins/iap/android/IapPlugin.kt +358 -0
  608. package/vendor/@akanjs/native/plugins/iap/ios/IapPlugin.swift +306 -0
  609. package/vendor/@akanjs/native/plugins/iap/native-plugin.json +28 -0
  610. package/vendor/@akanjs/native/plugins/iap/src/index.ts +206 -0
  611. package/vendor/@akanjs/native/plugins/keep-awake/android/KeepAwakePlugin.kt +48 -0
  612. package/vendor/@akanjs/native/plugins/keep-awake/ios/KeepAwakePlugin.swift +36 -0
  613. package/vendor/@akanjs/native/plugins/keep-awake/native-plugin.json +17 -0
  614. package/vendor/@akanjs/native/plugins/keep-awake/src/desktop.ts +127 -0
  615. package/vendor/@akanjs/native/plugins/keep-awake/src/index.ts +79 -0
  616. package/vendor/@akanjs/native/plugins/keep-awake/src/web.ts +78 -0
  617. package/vendor/@akanjs/native/plugins/keyboard/android/KeyboardPlugin.kt +77 -0
  618. package/vendor/@akanjs/native/plugins/keyboard/ios/KeyboardPlugin.swift +93 -0
  619. package/vendor/@akanjs/native/plugins/keyboard/native-plugin.json +18 -0
  620. package/vendor/@akanjs/native/plugins/keyboard/src/index.ts +78 -0
  621. package/vendor/@akanjs/native/plugins/keyboard/src/web.ts +57 -0
  622. package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotificationReceiver.kt +38 -0
  623. package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotifications.kt +284 -0
  624. package/vendor/@akanjs/native/plugins/local-notifications/android/LocalNotificationsPlugin.kt +248 -0
  625. package/vendor/@akanjs/native/plugins/local-notifications/ios/LocalNotificationsPlugin.swift +279 -0
  626. package/vendor/@akanjs/native/plugins/local-notifications/native-plugin.json +35 -0
  627. package/vendor/@akanjs/native/plugins/local-notifications/src/desktop.ts +196 -0
  628. package/vendor/@akanjs/native/plugins/local-notifications/src/index.ts +174 -0
  629. package/vendor/@akanjs/native/plugins/local-notifications/src/schedule.ts +164 -0
  630. package/vendor/@akanjs/native/plugins/local-notifications/src/timers.ts +72 -0
  631. package/vendor/@akanjs/native/plugins/local-notifications/src/web.ts +158 -0
  632. package/vendor/@akanjs/native/plugins/menu/native-plugin.json +10 -0
  633. package/vendor/@akanjs/native/plugins/menu/src/desktop.ts +52 -0
  634. package/vendor/@akanjs/native/plugins/menu/src/index.ts +107 -0
  635. package/vendor/@akanjs/native/plugins/network/android/NetworkPlugin.kt +124 -0
  636. package/vendor/@akanjs/native/plugins/network/ios/NetworkPlugin.swift +82 -0
  637. package/vendor/@akanjs/native/plugins/network/native-plugin.json +19 -0
  638. package/vendor/@akanjs/native/plugins/network/src/index.ts +59 -0
  639. package/vendor/@akanjs/native/plugins/network/src/web.ts +43 -0
  640. package/vendor/@akanjs/native/plugins/opener/android/OpenerPlugin.kt +81 -0
  641. package/vendor/@akanjs/native/plugins/opener/ios/OpenerPlugin.swift +83 -0
  642. package/vendor/@akanjs/native/plugins/opener/native-plugin.json +25 -0
  643. package/vendor/@akanjs/native/plugins/opener/src/desktop.ts +88 -0
  644. package/vendor/@akanjs/native/plugins/opener/src/index.ts +35 -0
  645. package/vendor/@akanjs/native/plugins/opener/src/url.ts +39 -0
  646. package/vendor/@akanjs/native/plugins/opener/src/web.ts +33 -0
  647. package/vendor/@akanjs/native/plugins/preferences/android/PreferencesPlugin.kt +44 -0
  648. package/vendor/@akanjs/native/plugins/preferences/ios/PreferencesPlugin.swift +47 -0
  649. package/vendor/@akanjs/native/plugins/preferences/native-plugin.json +18 -0
  650. package/vendor/@akanjs/native/plugins/preferences/src/desktop.ts +59 -0
  651. package/vendor/@akanjs/native/plugins/preferences/src/index.ts +75 -0
  652. package/vendor/@akanjs/native/plugins/preferences/src/web.ts +55 -0
  653. package/vendor/@akanjs/native/plugins/push/android/AkanNativeMessagingService.kt +17 -0
  654. package/vendor/@akanjs/native/plugins/push/android/PushPlugin.kt +257 -0
  655. package/vendor/@akanjs/native/plugins/push/ios/PushPlugin.swift +169 -0
  656. package/vendor/@akanjs/native/plugins/push/native-plugin.json +23 -0
  657. package/vendor/@akanjs/native/plugins/push/src/index.ts +73 -0
  658. package/vendor/@akanjs/native/plugins/screen/native-plugin.json +10 -0
  659. package/vendor/@akanjs/native/plugins/screen/src/desktop.ts +50 -0
  660. package/vendor/@akanjs/native/plugins/screen/src/index.ts +107 -0
  661. package/vendor/@akanjs/native/plugins/screen/src/web.ts +92 -0
  662. package/vendor/@akanjs/native/plugins/screen-orientation/android/ScreenOrientationPlugin.kt +113 -0
  663. package/vendor/@akanjs/native/plugins/screen-orientation/ios/ScreenOrientationPlugin.swift +150 -0
  664. package/vendor/@akanjs/native/plugins/screen-orientation/native-plugin.json +17 -0
  665. package/vendor/@akanjs/native/plugins/screen-orientation/src/index.ts +69 -0
  666. package/vendor/@akanjs/native/plugins/screen-orientation/src/types.ts +26 -0
  667. package/vendor/@akanjs/native/plugins/screen-orientation/src/web.ts +67 -0
  668. package/vendor/@akanjs/native/plugins/secure-storage/android/SecureStoragePlugin.kt +184 -0
  669. package/vendor/@akanjs/native/plugins/secure-storage/ios/SecureStoragePlugin.swift +145 -0
  670. package/vendor/@akanjs/native/plugins/secure-storage/native-plugin.json +18 -0
  671. package/vendor/@akanjs/native/plugins/secure-storage/src/desktop.ts +332 -0
  672. package/vendor/@akanjs/native/plugins/secure-storage/src/index.ts +33 -0
  673. package/vendor/@akanjs/native/plugins/share/android/SharePlugin.kt +218 -0
  674. package/vendor/@akanjs/native/plugins/share/ios/SharePlugin.swift +142 -0
  675. package/vendor/@akanjs/native/plugins/share/native-plugin.json +18 -0
  676. package/vendor/@akanjs/native/plugins/share/src/index.ts +87 -0
  677. package/vendor/@akanjs/native/plugins/share/src/options.ts +43 -0
  678. package/vendor/@akanjs/native/plugins/share/src/web.ts +116 -0
  679. package/vendor/@akanjs/native/plugins/single-instance/native-plugin.json +10 -0
  680. package/vendor/@akanjs/native/plugins/single-instance/src/desktop.ts +63 -0
  681. package/vendor/@akanjs/native/plugins/single-instance/src/index.ts +32 -0
  682. package/vendor/@akanjs/native/plugins/single-instance/src/socket.ts +248 -0
  683. package/vendor/@akanjs/native/plugins/splash-screen/android/SplashScreenPlugin.kt +19 -0
  684. package/vendor/@akanjs/native/plugins/splash-screen/ios/SplashScreenPlugin.swift +20 -0
  685. package/vendor/@akanjs/native/plugins/splash-screen/native-plugin.json +17 -0
  686. package/vendor/@akanjs/native/plugins/splash-screen/src/index.ts +24 -0
  687. package/vendor/@akanjs/native/plugins/splash-screen/src/web.ts +17 -0
  688. package/vendor/@akanjs/native/plugins/sqlite/android/SqlStatements.kt +121 -0
  689. package/vendor/@akanjs/native/plugins/sqlite/android/SqlitePlugin.kt +327 -0
  690. package/vendor/@akanjs/native/plugins/sqlite/ios/SqlitePlugin.swift +361 -0
  691. package/vendor/@akanjs/native/plugins/sqlite/native-plugin.json +18 -0
  692. package/vendor/@akanjs/native/plugins/sqlite/src/common.ts +221 -0
  693. package/vendor/@akanjs/native/plugins/sqlite/src/desktop.ts +140 -0
  694. package/vendor/@akanjs/native/plugins/sqlite/src/index.ts +114 -0
  695. package/vendor/@akanjs/native/plugins/toast/android/ToastPlugin.kt +27 -0
  696. package/vendor/@akanjs/native/plugins/toast/native-plugin.json +14 -0
  697. package/vendor/@akanjs/native/plugins/toast/src/index.ts +41 -0
  698. package/vendor/@akanjs/native/plugins/toast/src/queue.ts +77 -0
  699. package/vendor/@akanjs/native/plugins/toast/src/web.ts +130 -0
  700. package/vendor/@akanjs/native/plugins/tray/native-plugin.json +10 -0
  701. package/vendor/@akanjs/native/plugins/tray/src/desktop.ts +73 -0
  702. package/vendor/@akanjs/native/plugins/tray/src/index.ts +111 -0
  703. package/vendor/@akanjs/native/plugins/updates/android/UpdatesPlugin.kt +290 -0
  704. package/vendor/@akanjs/native/plugins/updates/ios/UpdatesPlugin.swift +292 -0
  705. package/vendor/@akanjs/native/plugins/updates/native-plugin.json +19 -0
  706. package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +558 -0
  707. package/vendor/@akanjs/native/plugins/updates/src/index.ts +95 -0
  708. package/vendor/@akanjs/native/plugins/window/native-plugin.json +32 -0
  709. package/vendor/@akanjs/native/plugins/window/src/desktop.ts +170 -0
  710. package/vendor/@akanjs/native/plugins/window/src/index.ts +342 -0
  711. package/vendor/@akanjs/native/plugins/window/src/web.ts +43 -0
  712. package/vendor/@akanjs/native/plugins/window-state/native-plugin.json +10 -0
  713. package/vendor/@akanjs/native/plugins/window-state/src/desktop.ts +73 -0
  714. package/vendor/@akanjs/native/plugins/window-state/src/index.ts +35 -0
  715. package/vendor/@akanjs/native/plugins/window-state/src/state.ts +146 -0
  716. package/webkit/bootCsr.tsx +26 -14
  717. package/webkit/index.ts +0 -2
  718. package/webkit/nativeNavigation.ts +116 -0
  719. package/webkit/nativePurchase.ts +93 -0
  720. package/webkit/useCamera.tsx +76 -71
  721. package/webkit/useCsrValues.ts +10 -124
  722. package/webkit/useGeoLocation.tsx +11 -13
  723. package/webkit/usePurchase.tsx +68 -123
  724. package/capacitor.base.config.ts +0 -140
  725. package/client/capacitor.ts +0 -252
  726. package/types/capacitor.base.config.d.ts +0 -3
  727. package/types/client/capacitor.d.ts +0 -290
  728. package/types/webkit/useCodepush.d.ts +0 -16
  729. package/types/webkit/useContact.d.ts +0 -11
  730. package/webkit/useCodepush.tsx +0 -76
  731. package/webkit/useContact.tsx +0 -45
@@ -0,0 +1,1320 @@
1
+
2
+
3
+ import { createHash } from "node:crypto";
4
+ import {
5
+ cpSync,
6
+ existsSync,
7
+ mkdirSync,
8
+ mkdtempSync,
9
+ readdirSync,
10
+ readFileSync,
11
+ renameSync,
12
+ rmSync,
13
+ statSync,
14
+ writeFileSync,
15
+ } from "node:fs";
16
+ import { homedir, tmpdir } from "node:os";
17
+ import { basename, dirname, join, relative, resolve } from "node:path";
18
+ import { assembleApk, assembleBundleModule, fileEntry, writeZip } from "../lib/apk.ts";
19
+ import { closureFor, type Library, licenseNotices, loadMavenLock, mavenCache, prepareLibraries } from "../lib/maven.ts";
20
+ import {
21
+ androidSdkRoot,
22
+ type Jdk,
23
+ javaEnv,
24
+ type KotlinToolchain,
25
+ resolveBuildTools,
26
+ resolveBundletool,
27
+ resolveJdk,
28
+ resolveKotlin,
29
+ TOOLCHAIN,
30
+ } from "../lib/toolchains.ts";
31
+
32
+ /** The license notices of an Android build with pinned Maven libraries, in the web root. */
33
+ export const LICENSES_FILE = "akan-native-licenses.json";
34
+
35
+ import { apiVersionsFor, checkApiLevels, formatApiProblems, loadApiVersions } from "../lib/apilevel.ts";
36
+ import type { ParsedArgs } from "../lib/args.ts";
37
+ import { makeNativeBoot } from "../lib/boot.ts";
38
+ import { type ExecResult, exec, execOrThrow } from "../lib/exec.ts";
39
+ import { googleServicesXml } from "../lib/googleservices.ts";
40
+ import { writeAndroidRes } from "../lib/icons.ts";
41
+ import {
42
+ type Device,
43
+ envFromProcess,
44
+ follow,
45
+ type Launched,
46
+ type LaunchOptions,
47
+ pipeLines,
48
+ printLine,
49
+ } from "../lib/launch.ts";
50
+ import { CliError, dim, log, ToolchainError } from "../lib/log.ts";
51
+ import { mergeLibraryManifests } from "../lib/manifestmerge.ts";
52
+ import { androidNameProblems } from "../lib/names.ts";
53
+ import {
54
+ androidPermissions,
55
+ androidPlugins,
56
+ kotlinFeatures,
57
+ kotlinRegistry,
58
+ type NativePlugin,
59
+ pluginMinSdk,
60
+ writePluginBindings,
61
+ } from "../lib/native-plugins.ts";
62
+ import { androidFeaturesFor, androidPermissionsFor } from "../lib/permissions.ts";
63
+ import { type AndroidSigning, type BuildContext, SigningError } from "../lib/prepare.ts";
64
+ import type { AndroidManifest, ResolvedConfig } from "../lib/project.ts";
65
+ import { PACKAGE_ROOT } from "../lib/root.ts";
66
+ import { updatesResource } from "../lib/updates.ts";
67
+ import { kotlinVectorData } from "../lib/vectors.ts";
68
+
69
+ const SHELL_SRC = join(PACKAGE_ROOT, "native", "android", "src");
70
+ /** Android 10. Newer framework APIs live in ApiN classes behind SDK_INT checks (lib/apilevel.ts). */
71
+ export const MIN_SDK = 29;
72
+ /** Chromium major: akan-native's runtime (Object.hasOwn 93) and unlowered ES2022 class static blocks (94). */
73
+ export const MIN_WEBVIEW = 94;
74
+ const TARGET_SDK = TOOLCHAIN.android.compileSdk;
75
+ const ACTIVITY = "com.akanjs.runtime.AkanNativeActivity";
76
+
77
+ interface AndroidTools {
78
+ sdk: string;
79
+ androidJar: string;
80
+ aapt2: string;
81
+ d8: string;
82
+ d8Jar: string;
83
+ apksigner: string;
84
+ adb: string;
85
+ emulator: string;
86
+ }
87
+
88
+ let buildToolsWarned = false;
89
+
90
+ /** SDK tools, pinned build-tools first (CLI-10). No JDK or Kotlin needed: see javaToolchain(). */
91
+ export function androidTools(): AndroidTools {
92
+ const sdk = androidSdkRoot();
93
+ if (!sdk) throw new ToolchainError("Android SDK not found (set ANDROID_HOME). Run `akan-native doctor android`.");
94
+ const bt = resolveBuildTools(sdk);
95
+ if (!bt)
96
+ throw new ToolchainError(
97
+ `Android build-tools ${TOOLCHAIN.android.buildTools} not found. Run \`akan-native doctor android\`.`,
98
+ );
99
+ if (bt.warning && !buildToolsWarned) {
100
+ log.warn(bt.warning);
101
+ buildToolsWarned = true;
102
+ }
103
+ const androidJar = join(sdk, "platforms", `android-${TARGET_SDK}`, "android.jar");
104
+ if (!existsSync(androidJar))
105
+ throw new ToolchainError(`${androidJar} missing: sdkmanager "platforms;android-${TARGET_SDK}"`);
106
+ return {
107
+ sdk,
108
+ androidJar,
109
+ aapt2: join(bt.dir, "aapt2"),
110
+ d8: join(bt.dir, "d8"),
111
+ d8Jar: join(bt.dir, "lib", "d8.jar"),
112
+ apksigner: join(bt.dir, "apksigner"),
113
+ adb: join(sdk, "platform-tools", "adb"),
114
+ emulator: join(sdk, "emulator", "emulator"),
115
+ };
116
+ }
117
+
118
+ interface JavaToolchain {
119
+ jdk: Jdk;
120
+ kotlin: KotlinToolchain;
121
+ /** JAVA_HOME + PATH for kotlinc, d8, R8, apksigner and keytool: one JDK for every Java tool. */
122
+ env: Record<string, string>;
123
+ }
124
+
125
+ /** The JDK and the pinned kotlinc (installed on first use, CLI-10). */
126
+ async function javaToolchain(): Promise<JavaToolchain> {
127
+ const jdk = resolveJdk();
128
+ if (!jdk) {
129
+ throw new ToolchainError(
130
+ `no JDK ${TOOLCHAIN.jdk.minMajor}+ found (JAVA_HOME, Android Studio, java_home, PATH). ` +
131
+ "Install Android Studio, or run `akan-native toolchain install jdk`, or set JAVA_HOME.",
132
+ );
133
+ }
134
+ const env = javaEnv(jdk);
135
+ const kotlin = await resolveKotlin({ javaEnv: env });
136
+ if (kotlin.warning) log.warn(kotlin.warning);
137
+ log.info(dim(`kotlinc ${kotlin.version} (${kotlin.source}), JDK ${jdk.version} (${jdk.source})`));
138
+ return { jdk, kotlin, env };
139
+ }
140
+
141
+ function xml(text: string): string {
142
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
143
+ }
144
+
145
+ const CONFIG_CHANGES =
146
+ "orientation|screenSize|screenLayout|smallestScreenSize|density|keyboard|keyboardHidden|navigation|uiMode|locale|layoutDirection|fontScale|fontWeightAdjustment|colorMode|touchscreen|mcc|mnc|grammaticalGender";
147
+
148
+ /**
149
+ * The applicationId: app.id, plus android.debugAppIdSuffix in debug builds so they install next to
150
+ * the release app (and match, say, a server's assetlinks entry for "<id>.debug").
151
+ */
152
+ export function androidAppId(ctx: BuildContext): string {
153
+ const { app, android } = ctx.project.config;
154
+ return app.id + (ctx.dev ? (android?.debugAppIdSuffix ?? "") : "");
155
+ }
156
+
157
+ export function androidManifest(
158
+ ctx: BuildContext,
159
+ permissions: string[],
160
+ applicationXml: string[],
161
+ manifestXml: string[] = [],
162
+ icon = false,
163
+ activityXml: string[] = [],
164
+ applicationAttrs: [string, string][] = [],
165
+ ): string {
166
+ const { config } = ctx.project;
167
+ const { app } = config;
168
+ const appId = androidAppId(ctx);
169
+ return `<?xml version="1.0" encoding="utf-8"?>
170
+ <!-- Generated by akan-native build. Do not edit. -->
171
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
172
+ package="${appId}"
173
+ android:versionCode="${app.build}"
174
+ android:versionName="${xml(app.version)}">
175
+
176
+ <uses-sdk android:minSdkVersion="${MIN_SDK}" android:targetSdkVersion="${TARGET_SDK}" />
177
+ <uses-permission android:name="android.permission.INTERNET" />
178
+ ${permissions.map((p) => ` <uses-permission android:name="${xml(p)}" />`).join("\n")}
179
+ ${manifestXml.map((x) => ` ${x.replaceAll("${applicationId}", appId)}`).join("\n")}
180
+
181
+ <application
182
+ android:name="com.akanjs.runtime.AkanNativeApplication"
183
+ android:label="${xml(app.name)}"
184
+ ${icon ? ` android:icon="@mipmap/ic_launcher"\n` : ""}${ctx.dev ? ` android:networkSecurityConfig="@xml/akan_native_network_security"\n` : ""} android:theme="@style/AkanNativeTheme"
185
+ android:allowBackup="false"
186
+ android:supportsRtl="true"
187
+ ${applicationAttrs.map(([n, v]) => ` ${n}="${xml(v)}"\n`).join("")} android:enableOnBackInvokedCallback="true">
188
+
189
+ <activity
190
+ android:name="${ACTIVITY}"
191
+ android:exported="true"
192
+ android:launchMode="singleTask"
193
+ android:windowSoftInputMode="adjustResize"
194
+ android:configChanges="${CONFIG_CHANGES}">
195
+ <intent-filter>
196
+ <action android:name="android.intent.action.MAIN" />
197
+ <category android:name="android.intent.category.LAUNCHER" />
198
+ </intent-filter>
199
+ ${config.deepLinks.schemes
200
+ .map(
201
+ (scheme) => ` <intent-filter>
202
+ <action android:name="android.intent.action.VIEW" />
203
+ <category android:name="android.intent.category.DEFAULT" />
204
+ <category android:name="android.intent.category.BROWSABLE" />
205
+ <data android:scheme="${xml(scheme)}" />
206
+ </intent-filter>`,
207
+ )
208
+ .join("\n")}
209
+ ${config.deepLinks.domains
210
+ .map(
211
+ ({
212
+ host,
213
+ pathPrefixes,
214
+ }) => ` <!-- App link (O5-2): verified against https://${xml(host)}/.well-known/assetlinks.json -->
215
+ <intent-filter android:autoVerify="true">
216
+ <action android:name="android.intent.action.VIEW" />
217
+ <category android:name="android.intent.category.DEFAULT" />
218
+ <category android:name="android.intent.category.BROWSABLE" />
219
+ <data android:scheme="https" />
220
+ <data android:host="${xml(host)}" />
221
+ ${pathPrefixes.map((prefix) => ` <data android:pathPrefix="${xml(prefix)}" />\n`).join("")} </intent-filter>`,
222
+ )
223
+ .join("\n")}
224
+ ${activityXml.map((x) => ` ${x.replaceAll("${applicationId}", appId)}`).join("\n")}
225
+ </activity>
226
+
227
+ <!-- Framework-only replacement for androidx FileProvider (camera EXTRA_OUTPUT, plugins.md C4) -->
228
+ <provider
229
+ android:name="com.akanjs.runtime.AkanNativeFileProvider"
230
+ android:authorities="${appId}.akan-native.files"
231
+ android:exported="false"
232
+ android:grantUriPermissions="true" />
233
+ ${applicationXml.map((x) => ` ${x.replaceAll("${applicationId}", appId)}`).join("\n")}
234
+ </application>
235
+ </manifest>
236
+ `;
237
+ }
238
+
239
+ const PROGUARD = `# Generated by akan-native build.
240
+ # The R8 command line does not read the manifest: keep its entry points explicitly.
241
+ -keep class com.akanjs.runtime.AkanNativeActivity { *; }
242
+ -keep class com.akanjs.runtime.AkanNativeApplication { *; }
243
+ -keep class com.akanjs.runtime.AkanNativeFileProvider { *; }
244
+ -keepattributes *Annotation*,SourceFile,LineNumberTable
245
+ -dontobfuscate
246
+ # kotlin-stdlib is compiled against the compile-only annotations-13.0.jar
247
+ -dontwarn org.jetbrains.annotations.**
248
+ `;
249
+
250
+ function sha(parts: (string | Uint8Array)[]): string {
251
+ const hash = createHash("sha256");
252
+ for (const part of parts) hash.update(part);
253
+ return hash.digest("hex");
254
+ }
255
+
256
+ /** Files of a folder tree with their content, for fingerprints. */
257
+ function treeParts(dir: string, prefix = ""): (string | Uint8Array)[] {
258
+ return readdirSync(dir)
259
+ .sort()
260
+ .flatMap((name) => {
261
+ const path = join(dir, name);
262
+ return statSync(path).isDirectory()
263
+ ? treeParts(path, `${prefix}${name}/`)
264
+ : [`${prefix}${name}`, readFileSync(path)];
265
+ });
266
+ }
267
+
268
+ function kotlinSources(dir: string): string[] {
269
+ return [...new Bun.Glob("**/*.kt").scanSync({ cwd: dir, absolute: true })].sort();
270
+ }
271
+
272
+ /** kotlin-stdlib dexed once per Kotlin version (dev builds put it in classes2.dex). */
273
+ async function stdlibDex(tools: AndroidTools, java: JavaToolchain): Promise<Uint8Array> {
274
+ const stdlib = java.kotlin.stdlib;
275
+ const key = sha([stdlib, String(statSync(stdlib).size), String(MIN_SDK)]).slice(0, 16);
276
+ const dir = join(homedir(), ".akan", "native", "cache", `kotlin-stdlib-dex-${key}`);
277
+ const dex = join(dir, "classes.dex");
278
+ if (!existsSync(dex)) {
279
+ log.step("dex: kotlin-stdlib (once per Kotlin version)");
280
+ mkdirSync(dir, { recursive: true });
281
+ await execOrThrow(
282
+ [tools.d8, "--debug", "--min-api", String(MIN_SDK), "--lib", tools.androidJar, "--output", dir, stdlib],
283
+ { env: java.env },
284
+ );
285
+ }
286
+ return new Uint8Array(readFileSync(dex));
287
+ }
288
+
289
+ async function debugKeystore(java: JavaToolchain): Promise<string> {
290
+ const path = join(homedir(), ".akan", "native", "debug.keystore");
291
+ if (!existsSync(path)) {
292
+ log.step("sign: creating ~/.akan/native/debug.keystore");
293
+ mkdirSync(join(homedir(), ".akan", "native"), { recursive: true });
294
+
295
+ await execOrThrow(
296
+ [
297
+ join(java.jdk.home, "bin", "keytool"),
298
+ "-genkeypair",
299
+ "-keystore",
300
+ path,
301
+ "-storepass",
302
+ "android",
303
+ "-keypass",
304
+ "android",
305
+ "-alias",
306
+ "androiddebugkey",
307
+ "-keyalg",
308
+ "RSA",
309
+ "-keysize",
310
+ "2048",
311
+ "-validity",
312
+ "10000",
313
+ "-dname",
314
+ "CN=Android Debug,O=Android,C=US",
315
+ "-noprompt",
316
+ ],
317
+ { echo: false, env: java.env },
318
+ );
319
+ }
320
+ return path;
321
+ }
322
+
323
+ export async function buildAndroid(ctx: BuildContext): Promise<string> {
324
+ const tools = androidTools();
325
+ const java = await javaToolchain();
326
+ const stdlib = java.kotlin.stdlib;
327
+ const { project, outDir } = ctx;
328
+ const { config } = project;
329
+ const release = !ctx.dev;
330
+ const plugins = androidPlugins(project.plugins);
331
+
332
+ const libraries = await mavenLibraries(plugins);
333
+ const libraryManifest = libraries.length
334
+ ? mergeLibraryManifests(
335
+ libraries
336
+ .filter((l) => l.manifest)
337
+ .map((l) => ({ from: l.coordinate, xml: readFileSync(l.manifest!, "utf8") })),
338
+ androidAppId(ctx),
339
+ )
340
+ : null;
341
+
342
+ const gen = join(outDir, "gen");
343
+ const obj = join(outDir, "obj");
344
+ const assets = join(outDir, "assets");
345
+
346
+ rmSync(join(gen, "kotlin"), { recursive: true, force: true });
347
+ mkdirSync(join(gen, "kotlin", "com", "akanjs", "generated"), { recursive: true });
348
+ mkdirSync(obj, { recursive: true });
349
+
350
+ const res = join(gen, "res");
351
+ rmSync(res, { recursive: true, force: true });
352
+ const { icon } = writeAndroidRes(res, config);
353
+ if (ctx.dev) {
354
+
355
+ mkdirSync(join(res, "xml"), { recursive: true });
356
+ writeFileSync(
357
+ join(res, "xml", "akan_native_network_security.xml"),
358
+ `<?xml version="1.0" encoding="utf-8"?>
359
+ <network-security-config>
360
+ <domain-config cleartextTrafficPermitted="true">
361
+ <domain includeSubdomains="false">localhost</domain>
362
+ <domain includeSubdomains="false">127.0.0.1</domain>
363
+ <domain includeSubdomains="false">10.0.2.2</domain>
364
+ </domain-config>
365
+ </network-security-config>
366
+ `,
367
+ );
368
+ }
369
+
370
+ if (config.android?.googleServices) {
371
+ mkdirSync(join(res, "values"), { recursive: true });
372
+ writeFileSync(
373
+ join(res, "values", "google_services.xml"),
374
+ googleServicesXml(
375
+ readFileSync(resolve(project.appDir, config.android.googleServices), "utf8"),
376
+ androidAppId(ctx),
377
+ config.app.id,
378
+ ),
379
+ );
380
+ } else if (plugins.some(({ plugin }) => plugin.manifest.id === "push")) {
381
+ log.warn(
382
+ "the push plugin needs android.googleServices (the Firebase project's google-services.json); register() fails without it",
383
+ );
384
+ }
385
+
386
+ const pushXml = plugins.some(({ plugin }) => plugin.manifest.id === "push")
387
+ ? pushResources(res, config, project.appDir)
388
+ : [];
389
+ if (!pushXml.length && config.push?.android && !plugins.some(({ plugin }) => plugin.manifest.id === "push"))
390
+ log.warn("push.android is set, but the push plugin is not in plugins");
391
+
392
+ for (const r of config.native?.resources ?? []) {
393
+ if (!r.to.startsWith("android/res/")) continue;
394
+ const target = join(res, r.to.slice("android/res/".length));
395
+ mkdirSync(dirname(target), { recursive: true });
396
+ cpSync(resolve(project.appDir, r.from), target);
397
+ }
398
+
399
+ const appNative = config.native?.android ?? {};
400
+ const applicationXml = [
401
+ ...plugins.flatMap(({ native }) => (native.applicationXml ? [native.applicationXml] : [])),
402
+ ...pushXml,
403
+ ...(appNative.application ?? []),
404
+ ];
405
+ const manifestXml = [
406
+ ...plugins.flatMap(({ native }) => (native.manifestXml ? [native.manifestXml] : [])),
407
+ ...androidFeaturesFor(config.permissions),
408
+ ...(appNative.manifest ?? []),
409
+ ];
410
+ const permissions = androidPermissions(plugins, androidPermissionsFor(config.permissions));
411
+
412
+ const allPermissions = [...new Set([...permissions, ...(libraryManifest?.permissions ?? [])])].filter(
413
+ (p) => p !== "android.permission.INTERNET",
414
+ );
415
+ writeFileSync(
416
+ join(gen, "AndroidManifest.xml"),
417
+ androidManifest(
418
+ ctx,
419
+ allPermissions,
420
+ [...applicationXml, ...(libraryManifest?.applicationXml ?? [])],
421
+ [...manifestXml, ...(libraryManifest?.manifestXml ?? [])],
422
+ icon,
423
+ appNative.activity ?? [],
424
+ libraryManifest?.applicationAttrs ?? [],
425
+ ),
426
+ );
427
+ writeFileSync(
428
+ join(gen, "kotlin", "com", "akanjs", "generated", "AkanNativeGeneratedPlugins.kt"),
429
+ kotlinRegistry(plugins, MIN_SDK, TOOLCHAIN.android.compileSdk),
430
+ );
431
+
432
+ mkdirSync(join(gen, "kotlin", "com", "akanjs", "runtime"), { recursive: true });
433
+ writeFileSync(join(gen, "kotlin", "com", "akanjs", "runtime", "AkanNativeVectorData.kt"), kotlinVectorData(ctx.dev));
434
+ writeFileSync(
435
+ join(gen, "kotlin", "com", "akanjs", "runtime", "AkanNativeFeatures.kt"),
436
+ kotlinFeatures({
437
+ dev: ctx.dev,
438
+ updates: config.updates !== null || plugins.some((p) => p.plugin.manifest.id === "updates"),
439
+ }),
440
+ );
441
+ const bindings = writePluginBindings(plugins, "android", join(gen, "spec"), project.appDir);
442
+ const clashes = androidNameProblems({
443
+ plugins: plugins.map((p) => ({
444
+ id: p.plugin.manifest.id,
445
+ className: p.native.class,
446
+ sources: p.sources.filter((s) => s.endsWith(".kt")),
447
+ })),
448
+ generated: bindings.filter((s) => s.endsWith(".kt")),
449
+ });
450
+ if (clashes.length) throw new CliError(`names clash in the Android app:\n - ${clashes.join("\n - ")}`);
451
+
452
+ const components = [...applicationXml.join("\n").matchAll(/android:name="([A-Za-z_][\w.$]*)"/g)]
453
+ .map((m) => m[1]!)
454
+ .filter((name) => name.includes(".") && !name.startsWith("android."));
455
+ const services = mergedServices(libraries);
456
+ const keep = [...new Set([...components, ...(libraryManifest?.components ?? [])])].map(
457
+ (name) => `-keep class ${name} { <init>(...); *; }`,
458
+ );
459
+
460
+ const serviceKeeps = [...services.values()].flat().map((impl) => `-keep class ${impl} { <init>(); }`);
461
+ const extra = plugins.flatMap(({ native }) => native.proguard ?? []);
462
+ writeFileSync(
463
+ join(gen, "proguard.pro"),
464
+ [PROGUARD, ...keep, ...serviceKeeps, ...extra, ...(libraries.length ? [MAVEN_PROGUARD] : []), ""].join("\n"),
465
+ );
466
+
467
+ rmSync(assets, { recursive: true, force: true });
468
+ cpSync(ctx.webDir, join(assets, "app"), { recursive: true });
469
+ writeFileSync(join(assets, "app", "index.html"), ctx.html);
470
+
471
+ if (libraries.length) {
472
+ if (existsSync(join(ctx.webDir, LICENSES_FILE)))
473
+ throw new CliError(
474
+ `${LICENSES_FILE} in web.dir is reserved: akan-native writes the Android build's license notices there`,
475
+ );
476
+ const notices = `${JSON.stringify(licenseNotices(libraries), null, 1)}\n`;
477
+ writeFileSync(join(assets, "app", LICENSES_FILE), notices);
478
+ writeFileSync(join(outDir, LICENSES_FILE), notices);
479
+ ctx.licenses = join(outDir, LICENSES_FILE);
480
+ }
481
+ for (const r of config.native?.resources ?? []) {
482
+ if (!r.to.startsWith("android/assets/")) continue;
483
+ const target = join(assets, r.to.slice("android/assets/".length));
484
+ mkdirSync(dirname(target), { recursive: true });
485
+ cpSync(resolve(project.appDir, r.from), target, { recursive: true });
486
+ }
487
+ mkdirSync(join(assets, "akan-native"), { recursive: true });
488
+ const boot = makeNativeBoot(ctx, "android");
489
+ writeFileSync(join(assets, "akan-native", "boot.json"), JSON.stringify(boot));
490
+ if (config.updates)
491
+ writeFileSync(
492
+ join(assets, "akan-native", "updates.json"),
493
+ updatesResource(config.updates, config.app, "android", boot.nativeApi, ctx.dev),
494
+ );
495
+ writeFileSync(join(assets, "akan-native", "env.runtime.json"), JSON.stringify(ctx.env, null, 2));
496
+ writeFileSync(
497
+ join(assets, "akan-native", "shell.json"),
498
+ JSON.stringify({
499
+ backgroundColor: config.shell.backgroundColor,
500
+ backgroundColorDark: config.shell.backgroundColorDark,
501
+ devtools: ctx.dev,
502
+ splash: { autoHide: config.splash.autoHide, timeout: config.splash.timeout },
503
+
504
+ externalSchemes: config.security?.shell?.externalSchemes ?? [],
505
+ minWebViewVersion: config.android?.minWebViewVersion ?? MIN_WEBVIEW,
506
+
507
+ keyboardResize: config.keyboard?.resize ?? "resize",
508
+
509
+ ...(ctx.dev && ctx.devServer ? { devServer: ctx.devServer } : {}),
510
+ ...(ctx.dev && ctx.startPath ? { startPath: ctx.startPath } : {}),
511
+ }),
512
+ );
513
+
514
+ const compiled = join(obj, "res.zip");
515
+ const resFingerprint = sha([tools.aapt2, ...treeParts(res)]);
516
+ const resStamp = join(obj, "res.sha256");
517
+ if (!existsSync(compiled) || !existsSync(resStamp) || readFileSync(resStamp, "utf8") !== resFingerprint) {
518
+ log.step("aapt2 compile: theme and icon");
519
+ rmSync(compiled, { force: true });
520
+ await execOrThrow([tools.aapt2, "compile", "--dir", res, "-o", compiled], { echo: false });
521
+ writeFileSync(resStamp, resFingerprint);
522
+ }
523
+ const overlays: string[] = [];
524
+ for (const lib of libraries) {
525
+ const flat = await compiledLibraryRes(tools.aapt2, lib);
526
+ if (flat) overlays.push("-R", flat);
527
+ }
528
+ const libraryPackages = [...new Set(libraries.filter((l) => l.hasResources && l.package).map((l) => l.package!))];
529
+ const linkArgs = [
530
+ "--manifest",
531
+ join(gen, "AndroidManifest.xml"),
532
+ "-I",
533
+ tools.androidJar,
534
+ compiled,
535
+ ...overlays,
536
+ ...(overlays.length ? ["--auto-add-overlay"] : []),
537
+ "--min-sdk-version",
538
+ String(MIN_SDK),
539
+ "--target-sdk-version",
540
+ String(TARGET_SDK),
541
+ "--version-code",
542
+ String(config.app.build),
543
+ "--version-name",
544
+ config.app.version,
545
+ ...(release ? [] : ["--debug-mode"]),
546
+ ];
547
+ const base = join(obj, "base.apk");
548
+ const rJava = join(obj, "r-java");
549
+ rmSync(rJava, { recursive: true, force: true });
550
+
551
+ const manifestKeeps = join(obj, "manifest-keep.pro");
552
+ await execOrThrow(
553
+ [
554
+ tools.aapt2,
555
+ "link",
556
+ "-o",
557
+ base,
558
+ ...linkArgs,
559
+ "--proguard",
560
+ manifestKeeps,
561
+ ...(libraryPackages.length ? ["--java", rJava, "--extra-packages", libraryPackages.join(":")] : []),
562
+ ],
563
+ { echo: false },
564
+ );
565
+ const rJar = libraryPackages.length
566
+ ? await compileRClasses(java, rJava, join(obj, "r-classes"), join(obj, "r.jar"))
567
+ : null;
568
+
569
+ const sources = [
570
+ ...kotlinSources(SHELL_SRC),
571
+ ...plugins.flatMap((p) => p.sources),
572
+ ...kotlinSources(join(gen, "kotlin")),
573
+ ...bindings,
574
+ ];
575
+ const libraryJars = libraries.map((l) => l.classes);
576
+ const fingerprint = sha([
577
+ release ? "release" : "debug",
578
+ java.kotlin.version,
579
+ java.kotlin.home,
580
+ java.jdk.home,
581
+ tools.androidJar,
582
+ ...libraryJars,
583
+
584
+ ...(release && rJar ? [readFileSync(rJar)] : []),
585
+ ...(release ? [readFileSync(manifestKeeps)] : []),
586
+ ...sources.flatMap((s) => [s, readFileSync(s)]),
587
+ ]);
588
+ const stamp = join(obj, "kotlin.sha256");
589
+ const classesDex = join(obj, "dex", "classes.dex");
590
+ if (!existsSync(stamp) || readFileSync(stamp, "utf8") !== fingerprint || !existsSync(classesDex)) {
591
+ log.step(`kotlinc: ${sources.length} files`);
592
+ rmSync(join(obj, "dex"), { recursive: true, force: true });
593
+ mkdirSync(join(obj, "dex"), { recursive: true });
594
+ const jar = join(obj, "classes.jar");
595
+ await execOrThrow(
596
+ [
597
+ java.kotlin.kotlinc,
598
+ ...sources,
599
+ "-d",
600
+ jar,
601
+ "-classpath",
602
+ [tools.androidJar, stdlib, ...libraryJars].join(":"),
603
+
604
+ "-jvm-target",
605
+ "17",
606
+ "-no-jdk",
607
+ "-no-stdlib",
608
+ "-no-reflect",
609
+ ...(release ? ["-Xno-param-assertions", "-Xno-call-assertions", "-Xno-receiver-assertions"] : []),
610
+ ],
611
+ { echo: false, env: java.env },
612
+ );
613
+ checkApis(jar, plugins, tools.androidJar);
614
+ if (release) {
615
+ log.step("dex: R8 (shrinks kotlin-stdlib)");
616
+ await execOrThrow(
617
+ [
618
+ java.jdk.java,
619
+ "-cp",
620
+ tools.d8Jar,
621
+ "com.android.tools.r8.R8",
622
+ "--release",
623
+ "--min-api",
624
+ String(MIN_SDK),
625
+ "--lib",
626
+ tools.androidJar,
627
+ "--pg-conf",
628
+ join(gen, "proguard.pro"),
629
+ "--pg-conf",
630
+ manifestKeeps,
631
+ "--pg-map-output",
632
+ join(obj, "mapping.txt"),
633
+
634
+ ...libraries.flatMap((l) => (l.proguard ? ["--pg-conf", l.proguard] : [])),
635
+ "--output",
636
+ join(obj, "dex"),
637
+ jar,
638
+ stdlib,
639
+ ...libraryJars,
640
+ ...(rJar ? [rJar] : []),
641
+ ],
642
+ { echo: false, env: java.env },
643
+ );
644
+ } else {
645
+ log.step("dex: d8 (app classes)");
646
+ await execOrThrow(
647
+ [
648
+ tools.d8,
649
+ "--debug",
650
+ "--min-api",
651
+ String(MIN_SDK),
652
+ "--lib",
653
+ tools.androidJar,
654
+ ...[stdlib, ...libraryJars].flatMap((cp) => ["--classpath", cp]),
655
+ "--output",
656
+ join(obj, "dex"),
657
+ jar,
658
+ ],
659
+ { echo: false, env: java.env },
660
+ );
661
+ }
662
+ writeFileSync(stamp, fingerprint);
663
+ } else {
664
+ log.info(dim("kotlin: unchanged, reusing dex"));
665
+ }
666
+
667
+ const dexFiles = readdirSync(join(obj, "dex"))
668
+ .filter((f) => /^classes\d*\.dex$/.test(f))
669
+ .sort((a, b) => dexIndex(a) - dexIndex(b));
670
+ const dex: Uint8Array[] = dexFiles.map((f) => new Uint8Array(readFileSync(join(obj, "dex", f))));
671
+ if (!release) {
672
+ dex.push(await stdlibDex(tools, java));
673
+
674
+ if (libraries.length) dex.push(...(await libraryDex(tools, java, libraryJars)));
675
+ if (rJar) dex.push(...(await dexFilesOf(tools, java, rJar, join(obj, "r-dex"))));
676
+ }
677
+
678
+ const packaged = [
679
+ ...[...services].map(([name, impls]) => ({
680
+ name: `META-INF/services/${name}`,
681
+ bytes: new TextEncoder().encode(`${impls.join("\n")}\n`),
682
+ })),
683
+ ...libraries.flatMap((l) =>
684
+ l.nativeLibs.map((n) => ({ name: `lib/${n.abi}/${n.name}`, bytes: new Uint8Array(readFileSync(n.path)) })),
685
+ ),
686
+ ];
687
+ const key = await signingKey(ctx, java);
688
+ const unsigned = join(obj, "unsigned.apk");
689
+ writeFileSync(
690
+ unsigned,
691
+ assembleApk({ base: new Uint8Array(readFileSync(base)), dex, assetsDir: assets, extra: packaged }),
692
+ );
693
+ const apk = join(outDir, `${basename(config.app.id)}${release ? "" : "-debug"}.apk`);
694
+ try {
695
+ await execOrThrow(
696
+ [
697
+ tools.apksigner,
698
+ "sign",
699
+ "--ks",
700
+ key.keystore,
701
+ "--ks-key-alias",
702
+ key.alias,
703
+ "--ks-pass",
704
+ "env:AKAN_NATIVE_KS_PASS",
705
+ "--key-pass",
706
+ "env:AKAN_NATIVE_KEY_PASS",
707
+ "--v1-signing-enabled",
708
+ "false",
709
+ "--out",
710
+ apk,
711
+ unsigned,
712
+ ],
713
+ { echo: false, env: { ...java.env, ...key.env } },
714
+ );
715
+ } catch (error) {
716
+ if (key.release)
717
+ throw new SigningError(
718
+ `signing with ${key.keystore} (alias ${key.alias}) failed: ${(error as Error).message.split("\n").slice(1).join(" ").trim()}`,
719
+ );
720
+ throw error;
721
+ }
722
+ log.info(
723
+ dim(
724
+ `size ${(statSync(apk).size / 1024).toFixed(0)} KiB${key.release ? `, signed with ${basename(key.keystore)} (${key.alias})` : ""}`,
725
+ ),
726
+ );
727
+ ctx.signedAs = key.release ? "distribution" : "debug";
728
+
729
+ if (ctx.android?.bundle) {
730
+ const proto = join(obj, "base-proto.zip");
731
+ await execOrThrow([tools.aapt2, "link", "--proto-format", "-o", proto, ...linkArgs], { echo: false });
732
+ const module = join(obj, "base-module.zip");
733
+ writeFileSync(
734
+ module,
735
+ assembleBundleModule({ base: new Uint8Array(readFileSync(proto)), dex, assetsDir: assets, extra: packaged }),
736
+ );
737
+ const aab = join(outDir, `${basename(config.app.id)}${release ? "" : "-debug"}.aab`);
738
+ log.step("bundle: bundletool build-bundle");
739
+ await execOrThrow(
740
+ [
741
+ java.jdk.java,
742
+ "-jar",
743
+ await resolveBundletool(),
744
+ "build-bundle",
745
+ `--modules=${module}`,
746
+ `--output=${aab}`,
747
+ "--overwrite",
748
+ ],
749
+ { echo: false, env: java.env },
750
+ );
751
+ try {
752
+ await execOrThrow(
753
+ [
754
+ join(java.jdk.home, "bin", "jarsigner"),
755
+ "-keystore",
756
+ key.keystore,
757
+ "-storepass:env",
758
+ "AKAN_NATIVE_KS_PASS",
759
+ "-keypass:env",
760
+ "AKAN_NATIVE_KEY_PASS",
761
+ aab,
762
+ key.alias,
763
+ ],
764
+ {
765
+ echo: false,
766
+ env: { ...java.env, ...key.env },
767
+ },
768
+ );
769
+ } catch (error) {
770
+ if (key.release)
771
+ throw new SigningError(
772
+ `signing the bundle with ${key.keystore} (alias ${key.alias}) failed: ${(error as Error).message.split("\n").slice(1).join(" ").trim()}`,
773
+ );
774
+ throw error;
775
+ }
776
+ log.info(dim(`bundle ${(statSync(aab).size / 1024).toFixed(0)} KiB: ${basename(aab)}`));
777
+ ctx.artifacts.push({ kind: "aab", path: aab });
778
+ }
779
+ return apk;
780
+ }
781
+
782
+ /** Rules for code the pinned libraries reference but do not ship (optional dependencies Gradle apps also leave out). */
783
+ const MAVEN_PROGUARD = `# Pinned Maven libraries (native/android/maven.lock.json): optional dependencies they never load here.
784
+ -dontwarn com.google.errorprone.annotations.**
785
+ -dontwarn javax.annotation.**
786
+ -dontwarn org.checkerframework.**
787
+ -dontwarn com.google.j2objc.annotations.**
788
+ -dontwarn org.codehaus.mojo.animal_sniffer.**`;
789
+
790
+ /** The closure the plugins' android.maven roots name, downloaded and unpacked; none without roots. */
791
+ async function mavenLibraries(plugins: NativePlugin<AndroidManifest>[]): Promise<Library[]> {
792
+ const roots = plugins.flatMap(({ native }) => native.maven ?? []);
793
+ if (!roots.length) return [];
794
+ const closure = closureFor(loadMavenLock(), roots)!;
795
+ const libraries = await prepareLibraries(closure.artifacts);
796
+ log.info(dim(`maven: ${closure.name} closure, ${libraries.length} pinned libraries`));
797
+ return libraries;
798
+ }
799
+
800
+ /** META-INF/services files of all libraries, one list of implementations per service. */
801
+ function mergedServices(libraries: Library[]): Map<string, string[]> {
802
+ const out = new Map<string, string[]>();
803
+ for (const lib of libraries) {
804
+ for (const service of lib.services) {
805
+ const impls = readFileSync(service.path, "utf8")
806
+ .split("\n")
807
+ .map((l) => l.replace(/#.*/, "").trim())
808
+ .filter(Boolean);
809
+ const list = out.get(service.name) ?? [];
810
+ for (const impl of impls) if (!list.includes(impl)) list.push(impl);
811
+ out.set(service.name, list);
812
+ }
813
+ }
814
+ return out;
815
+ }
816
+
817
+ /** An AAR's res/ compiled once per aapt2 (flat files for `aapt2 link -R`). */
818
+ async function compiledLibraryRes(aapt2: string, lib: Library): Promise<string | null> {
819
+ if (!lib.res) return null;
820
+ const out = join(mavenCache(), "compiled", `${sha([aapt2, lib.res]).slice(0, 32)}.zip`);
821
+ if (existsSync(out)) return out;
822
+ mkdirSync(dirname(out), { recursive: true });
823
+ const tmp = `${out}.${process.pid}.tmp`;
824
+ await execOrThrow([aapt2, "compile", "--dir", lib.res, "-o", tmp], { echo: false });
825
+ renameSync(tmp, out);
826
+ return out;
827
+ }
828
+
829
+ /** The R.java files aapt2 wrote, compiled with the JDK's javac and packed as a jar. */
830
+ async function compileRClasses(java: JavaToolchain, sources: string, classes: string, jar: string): Promise<string> {
831
+ const files = walkFiles(sources).filter((f) => f.endsWith(".java"));
832
+ rmSync(classes, { recursive: true, force: true });
833
+ mkdirSync(classes, { recursive: true });
834
+ await execOrThrow(
835
+ [join(java.jdk.home, "bin", "javac"), "-nowarn", "-encoding", "UTF-8", "--release", "17", "-d", classes, ...files],
836
+ { echo: false, env: java.env },
837
+ );
838
+ writeFileSync(
839
+ jar,
840
+ writeZip(
841
+ walkFiles(classes).map((f) =>
842
+ fileEntry(relative(classes, f).split("\\").join("/"), new Uint8Array(readFileSync(f)), false),
843
+ ),
844
+ ),
845
+ );
846
+ return jar;
847
+ }
848
+
849
+ function walkFiles(dir: string): string[] {
850
+ if (!existsSync(dir)) return [];
851
+ return readdirSync(dir).flatMap((name) => {
852
+ const path = join(dir, name);
853
+ return statSync(path).isDirectory() ? walkFiles(path) : [path];
854
+ });
855
+ }
856
+
857
+ /** Debug builds: the libraries' dex, made once per closure and cached like kotlin-stdlib's. */
858
+ async function libraryDex(tools: AndroidTools, java: JavaToolchain, jars: string[]): Promise<Uint8Array[]> {
859
+ const key = sha([tools.d8, String(MIN_SDK), java.kotlin.stdlib, ...jars]).slice(0, 16);
860
+ const dir = join(homedir(), ".akan", "native", "cache", `maven-dex-${key}`);
861
+ if (!existsSync(join(dir, "classes.dex"))) {
862
+ log.step(`dex: ${jars.length} pinned libraries (once per closure)`);
863
+ const tmp = `${dir}.${process.pid}.tmp`;
864
+ rmSync(tmp, { recursive: true, force: true });
865
+ mkdirSync(tmp, { recursive: true });
866
+ await execOrThrow(
867
+ [
868
+ tools.d8,
869
+ "--debug",
870
+ "--min-api",
871
+ String(MIN_SDK),
872
+ "--lib",
873
+ tools.androidJar,
874
+ "--classpath",
875
+ java.kotlin.stdlib,
876
+ "--output",
877
+ tmp,
878
+ ...jars,
879
+ ],
880
+ { echo: false, env: java.env },
881
+ );
882
+ rmSync(dir, { recursive: true, force: true });
883
+ renameSync(tmp, dir);
884
+ }
885
+ return dexIn(dir);
886
+ }
887
+
888
+ /** A jar dexed into `out` (the R classes of a debug build). */
889
+ async function dexFilesOf(tools: AndroidTools, java: JavaToolchain, jar: string, out: string): Promise<Uint8Array[]> {
890
+ rmSync(out, { recursive: true, force: true });
891
+ mkdirSync(out, { recursive: true });
892
+ await execOrThrow(
893
+ [tools.d8, "--debug", "--min-api", String(MIN_SDK), "--lib", tools.androidJar, "--output", out, jar],
894
+ { echo: false, env: java.env },
895
+ );
896
+ return dexIn(out);
897
+ }
898
+
899
+ function dexIn(dir: string): Uint8Array[] {
900
+ return readdirSync(dir)
901
+ .filter((f) => /^classes\d*\.dex$/.test(f))
902
+ .sort((a, b) => dexIndex(a) - dexIndex(b))
903
+ .map((f) => new Uint8Array(readFileSync(join(dir, f))));
904
+ }
905
+
906
+ const dexIndex = (name: string) => Number(/^classes(\d*)\.dex$/.exec(name)?.[1] || 1);
907
+
908
+ /**
909
+ * The key a build signs with, and the child env that carries its passwords (apksigner and jarsigner
910
+ * read env:NAME, so they appear on no command line). Release builds use the app's key from the
911
+ * build options or AKAN_NATIVE_ANDROID_KEYSTORE, AKAN_NATIVE_ANDROID_KEY_ALIAS, AKAN_NATIVE_ANDROID_KEYSTORE_PASSWORD and
912
+ * AKAN_NATIVE_ANDROID_KEY_PASSWORD; without one they fall back to ~/.akan/native/debug.keystore with a warning.
913
+ */
914
+ async function signingKey(
915
+ ctx: BuildContext,
916
+ java: JavaToolchain,
917
+ ): Promise<{ keystore: string; alias: string; env: Record<string, string>; release: boolean }> {
918
+
919
+ const configured = ctx.dev ? undefined : (ctx.android?.signing ?? (ctx.api ? undefined : signingFromEnv()));
920
+ if (configured) {
921
+ const keystore = resolve(ctx.project.appDir, configured.keystore);
922
+ if (!existsSync(keystore)) throw new SigningError(`keystore ${keystore} not found`);
923
+ if (!configured.alias || !configured.storePassword)
924
+ throw new SigningError("the release key needs an alias and a store password");
925
+ return {
926
+ keystore,
927
+ alias: configured.alias,
928
+ env: {
929
+ AKAN_NATIVE_KS_PASS: configured.storePassword,
930
+ AKAN_NATIVE_KEY_PASS: configured.keyPassword ?? configured.storePassword,
931
+ },
932
+ release: true,
933
+ };
934
+ }
935
+ if (!ctx.dev) {
936
+ log.warn(
937
+ ctx.api
938
+ ? "release build signed with ~/.akan/native/debug.keystore: fine for testing, not for Google Play (pass signing to release())"
939
+ : "release build signed with ~/.akan/native/debug.keystore: fine for testing, not for Google Play (set AKAN_NATIVE_ANDROID_KEYSTORE, AKAN_NATIVE_ANDROID_KEY_ALIAS and AKAN_NATIVE_ANDROID_KEYSTORE_PASSWORD)",
940
+ );
941
+ }
942
+ return {
943
+ keystore: await debugKeystore(java),
944
+ alias: "androiddebugkey",
945
+ env: { AKAN_NATIVE_KS_PASS: "android", AKAN_NATIVE_KEY_PASS: "android" },
946
+ release: false,
947
+ };
948
+ }
949
+
950
+ function signingFromEnv(env: Record<string, string | undefined> = process.env): AndroidSigning | undefined {
951
+ const keystore = env.AKAN_NATIVE_ANDROID_KEYSTORE;
952
+ if (!keystore) return undefined;
953
+ return {
954
+ keystore,
955
+ alias: env.AKAN_NATIVE_ANDROID_KEY_ALIAS ?? "",
956
+ storePassword: env.AKAN_NATIVE_ANDROID_KEYSTORE_PASSWORD ?? "",
957
+ keyPassword: env.AKAN_NATIVE_ANDROID_KEY_PASSWORD,
958
+ };
959
+ }
960
+
961
+ /**
962
+ * push.android (N13) → resources and <application> meta-data: Firebase's default channel, icon and
963
+ * color for the notifications it shows itself (the app not in front), and the channel's name and
964
+ * importance for the plugin, which creates the channel at startup so Firebase finds it later.
965
+ */
966
+ export function pushResources(res: string, config: Pick<ResolvedConfig, "push">, appDir: string): string[] {
967
+ const settings = config.push?.android;
968
+ if (!settings) return [];
969
+ const meta = (name: string, attr: "value" | "resource", value: string) =>
970
+ `<meta-data android:name="${name}" android:${attr}="${xml(value)}" />`;
971
+ const out: string[] = [];
972
+ if (settings.channel) {
973
+ const { id, name, importance = "default", description } = settings.channel;
974
+ out.push(meta("com.google.firebase.messaging.default_notification_channel_id", "value", id));
975
+ out.push(
976
+ meta("com.akanjs.push.channel_name", "value", name),
977
+ meta("com.akanjs.push.channel_importance", "value", importance),
978
+ );
979
+ if (description) out.push(meta("com.akanjs.push.channel_description", "value", description));
980
+ }
981
+ if (settings.smallIcon) {
982
+ mkdirSync(join(res, "drawable-xxxhdpi"), { recursive: true });
983
+ cpSync(resolve(appDir, settings.smallIcon), join(res, "drawable-xxxhdpi", "akan_native_push_icon.png"));
984
+ out.push(
985
+ meta("com.google.firebase.messaging.default_notification_icon", "resource", "@drawable/akan_native_push_icon"),
986
+ );
987
+ }
988
+ if (settings.color) {
989
+ mkdirSync(join(res, "values"), { recursive: true });
990
+ writeFileSync(
991
+ join(res, "values", "akan_native_push.xml"),
992
+ `<?xml version="1.0" encoding="utf-8"?>\n<resources>\n <color name="akan_native_push_color">${settings.color}</color>\n</resources>\n`,
993
+ );
994
+ out.push(
995
+ meta("com.google.firebase.messaging.default_notification_color", "resource", "@color/akan_native_push_color"),
996
+ );
997
+ }
998
+ return out;
999
+ }
1000
+
1001
+ /** A connected serial as a Device: an emulator's AVD name or the model, and the Android version. */
1002
+ async function describeSerial(adb: string, serial: string, state: Device["state"]): Promise<Device> {
1003
+ const emulator = serial.startsWith("emulator-");
1004
+ const online = state === "booted" || state === "connected";
1005
+ const run = async (args: string[]) =>
1006
+ online ? ((await exec([adb, "-s", serial, ...args], { echo: false })).stdout.split(/\r?\n/)[0]?.trim() ?? "") : "";
1007
+ const [avd, release, sdk, model] = await Promise.all([
1008
+ emulator ? run(["emu", "avd", "name"]) : "",
1009
+ run(["shell", "getprop", "ro.build.version.release"]),
1010
+ run(["shell", "getprop", "ro.build.version.sdk"]),
1011
+ run(["shell", "getprop", "ro.product.model"]),
1012
+ ]);
1013
+ return {
1014
+ platform: "android",
1015
+ id: serial,
1016
+ name: avd || model || serial,
1017
+ kind: emulator ? "emulator" : "device",
1018
+ os: sdk ? `Android ${release} (API ${sdk})` : "",
1019
+ state,
1020
+ };
1021
+ }
1022
+
1023
+ /** "API 37" from an AVD's ini (target=android-37.0), or "". */
1024
+ function avdApi(name: string): string {
1025
+ const ini = join(process.env.ANDROID_AVD_HOME ?? join(homedir(), ".android", "avd"), `${name}.ini`);
1026
+ const target = existsSync(ini) ? /^target=android-(\d+)/m.exec(readFileSync(ini, "utf8"))?.[1] : undefined;
1027
+ return target ? `API ${target}` : "";
1028
+ }
1029
+
1030
+ /** Connected devices and emulators, then AVDs that are not running (docs/api.md devices). */
1031
+ export async function androidDevices(): Promise<Device[]> {
1032
+ const tools = androidTools();
1033
+ const rows = (await exec([tools.adb, "devices"], { echo: false })).stdout
1034
+ .split("\n")
1035
+ .slice(1)
1036
+ .map((l) => l.trim().split(/\s+/))
1037
+ .filter((c) => c[0]);
1038
+ const running = await Promise.all(
1039
+ rows.map(([serial = "", state]) =>
1040
+ describeSerial(
1041
+ tools.adb,
1042
+ serial,
1043
+ state === "device"
1044
+ ? serial.startsWith("emulator-")
1045
+ ? "booted"
1046
+ : "connected"
1047
+ : state === "unauthorized"
1048
+ ? "unauthorized"
1049
+ : "offline",
1050
+ ),
1051
+ ),
1052
+ );
1053
+ const runningAvds = new Set(running.filter((d) => d.kind === "emulator").map((d) => d.name));
1054
+ const avds = (await exec([tools.emulator, "-list-avds"], { echo: false })).stdout
1055
+ .split("\n")
1056
+ .map((s) => s.trim())
1057
+ .filter((s) => s && !s.startsWith("INFO"));
1058
+ const stopped = avds
1059
+ .filter((name) => !runningAvds.has(name))
1060
+ .map(
1061
+ (name): Device => ({
1062
+ platform: "android",
1063
+ id: name,
1064
+ name,
1065
+ kind: "emulator",
1066
+ os: avdApi(name),
1067
+ state: "shutdown",
1068
+ }),
1069
+ );
1070
+ return [...running, ...stopped];
1071
+ }
1072
+
1073
+ async function onlineDevices(adb: string): Promise<string[]> {
1074
+ const out = (await exec([adb, "devices"], { echo: false })).stdout;
1075
+ return out
1076
+ .split("\n")
1077
+ .slice(1)
1078
+ .map((l) => l.trim().split(/\s+/))
1079
+ .filter((c) => c[1] === "device")
1080
+ .map((c) => c[0]!);
1081
+ }
1082
+
1083
+ /**
1084
+ * `akan-native test` starts emulators with -no-window, and run/dev reuse whatever is connected, so the app
1085
+ * can end up on an emulator nobody can see. Found by the AVD name (`adb emu avd name`) in the
1086
+ * emulator's command line; the window-less build is also a separate `qemu-system-*-headless` binary.
1087
+ */
1088
+ export async function warnIfWindowless(adb: string, serial: string): Promise<void> {
1089
+ if (!serial.startsWith("emulator-")) return;
1090
+ const avd = (await exec([adb, "-s", serial, "emu", "avd", "name"], { echo: false })).stdout.split(/\r?\n/)[0]?.trim();
1091
+ if (!avd) return;
1092
+ const ps = (await exec(["ps", "-axo", "command"], { echo: false })).stdout.split("\n");
1093
+ const line = ps.find(
1094
+ (l) => /qemu-system-\S+/.test(l) && l.split(/\s+/).some((arg, i, all) => arg === avd && all[i - 1] === "-avd"),
1095
+ );
1096
+ if (!line || !(line.includes(" -no-window") || /qemu-system-\S+-headless /.test(line))) return;
1097
+ log.warn(
1098
+ `${serial} (${avd}) is running without a window (started by \`akan-native test\` or --headless), so the app will not be visible.`,
1099
+ );
1100
+ log.info(dim(`To see it: ${adb} -s ${serial} emu kill, then run this again.`));
1101
+ }
1102
+
1103
+ /**
1104
+ * The device to use (O4-4): `wanted` is a connected device's serial (`adb devices`: a phone over USB
1105
+ * or Wi-Fi, a running emulator) or an AVD name; without it the first connected device, else the
1106
+ * first AVD is started.
1107
+ */
1108
+ async function ensureDevice(tools: AndroidTools, wanted: string | undefined, headless: boolean): Promise<string> {
1109
+ let devices = await onlineDevices(tools.adb);
1110
+ if (wanted && devices.includes(wanted)) devices = [wanted];
1111
+ else if (wanted) {
1112
+
1113
+ const running = [];
1114
+ for (const serial of devices.filter((s) => s.startsWith("emulator-"))) {
1115
+ const name = (await exec([tools.adb, "-s", serial, "emu", "avd", "name"], { echo: false })).stdout
1116
+ .split(/\r?\n/)[0]
1117
+ ?.trim();
1118
+ if (name === wanted) running.push(serial);
1119
+ }
1120
+ devices = running;
1121
+ }
1122
+ if (devices.length === 0) {
1123
+ const avds = (await exec([tools.emulator, "-list-avds"], { echo: false })).stdout
1124
+ .split("\n")
1125
+ .map((s) => s.trim())
1126
+ .filter(Boolean);
1127
+ if (wanted && !avds.includes(wanted))
1128
+ throw new CliError(
1129
+ `no connected Android device with serial ${wanted} and no AVD of that name (adb devices; emulator -list-avds: ${avds.join(", ") || "none"})`,
1130
+ );
1131
+ const avd = wanted ?? avds[0];
1132
+ if (!avd) throw new CliError("no Android device or AVD found. Create one in Android Studio (Device Manager).");
1133
+ log.step(`starting emulator ${avd}`);
1134
+ const emulatorArgs = [
1135
+ "-avd",
1136
+ avd,
1137
+ "-no-snapshot-save",
1138
+ "-no-boot-anim",
1139
+ ...(headless ? ["-no-window", "-no-audio"] : []),
1140
+ ];
1141
+ const before = new Set(
1142
+ await exec([tools.adb, "devices"], { echo: false }).then((r) =>
1143
+ [...r.stdout.matchAll(/^(emulator-\d+)\s/gm)].map((m) => m[1]!),
1144
+ ),
1145
+ );
1146
+ Bun.spawn([tools.emulator, ...emulatorArgs], { stdio: ["ignore", "ignore", "ignore"] }).unref();
1147
+
1148
+ const deadline = Date.now() + 180_000;
1149
+ for (;;) {
1150
+ const serials = [...(await exec([tools.adb, "devices"], { echo: false })).stdout.matchAll(/^(emulator-\d+)\s/gm)]
1151
+ .map((m) => m[1]!)
1152
+ .filter((s) => !before.has(s));
1153
+ let found: string | undefined;
1154
+ for (const serial of serials) {
1155
+ const name = (await exec([tools.adb, "-s", serial, "emu", "avd", "name"], { echo: false })).stdout
1156
+ .split(/\r?\n/)[0]
1157
+ ?.trim();
1158
+ if (name === avd) found = serial;
1159
+ }
1160
+ if (found) {
1161
+ await execOrThrow([tools.adb, "-s", found, "wait-for-device"], { echo: false });
1162
+ devices = [found];
1163
+ break;
1164
+ }
1165
+ if (Date.now() > deadline) throw new CliError(`the emulator ${avd} did not come up in adb devices`);
1166
+ await Bun.sleep(1000);
1167
+ }
1168
+ }
1169
+ const serial = devices[0]!;
1170
+ if (!headless) await warnIfWindowless(tools.adb, serial);
1171
+ const deadline = Date.now() + 180_000;
1172
+ while (
1173
+ (await exec([tools.adb, "-s", serial, "shell", "getprop", "sys.boot_completed"], { echo: false })).stdout.trim() !==
1174
+ "1"
1175
+ ) {
1176
+ if (Date.now() > deadline) throw new CliError(`${serial} did not finish booting`);
1177
+ await Bun.sleep(1000);
1178
+ }
1179
+ return serial;
1180
+ }
1181
+
1182
+ function shellQuote(text: string): string {
1183
+ return `'${text.replace(/'/g, `'\\''`)}'`;
1184
+ }
1185
+
1186
+ export async function launchAndroid(
1187
+ ctx: BuildContext,
1188
+ apk: string,
1189
+ opts: LaunchOptions & { avd?: string; device?: string; reverse?: number[] },
1190
+ ): Promise<Launched> {
1191
+ const tools = androidTools();
1192
+ const serial = await ensureDevice(tools, opts.device ?? opts.avd, opts.headless);
1193
+ const adb = [tools.adb, "-s", serial];
1194
+ const appId = androidAppId(ctx);
1195
+
1196
+ const reverse = opts.reverse ?? [];
1197
+ for (const port of reverse) await execOrThrow([...adb, "reverse", `tcp:${port}`, `tcp:${port}`], { echo: false });
1198
+ log.step(`install on ${serial}`);
1199
+ await execOrThrow([...adb, "install", "-r", apk], { echo: false });
1200
+ await exec([...adb, "logcat", "-c"], { echo: false });
1201
+
1202
+ const overrides: Record<string, string> = {};
1203
+ for (const [key, value] of Object.entries(opts.env)) overrides[key.replace(/^AKAN_NATIVE_/, "")] = value;
1204
+ const extra = Object.keys(overrides).length ? ` --es akanNativeEnv ${shellQuote(JSON.stringify(overrides))}` : "";
1205
+
1206
+ await execOrThrow([...adb, "shell", `am start -S -W -n ${appId}/${ACTIVITY}${extra}`], { echo: false });
1207
+ let pid = "";
1208
+ for (let i = 0; i < 20 && !pid; i++) {
1209
+ pid = (await exec([...adb, "shell", "pidof", appId], { echo: false })).stdout.trim();
1210
+ if (!pid) await Bun.sleep(250);
1211
+ }
1212
+
1213
+ const logcat = Bun.spawn(
1214
+ [
1215
+ ...adb,
1216
+ "logcat",
1217
+ "-v",
1218
+ "brief",
1219
+ ...(pid ? [`--pid=${pid}`] : []),
1220
+ "AkanNative:V",
1221
+ "AkanNativeConsole:V",
1222
+ "AndroidRuntime:E",
1223
+ "*:S",
1224
+ ],
1225
+ { stdin: "ignore", stdout: "pipe", stderr: "pipe" },
1226
+ );
1227
+ const onLine = opts.onLine ?? printLine;
1228
+ const logs = Promise.all([pipeLines(logcat.stdout, onLine), pipeLines(logcat.stderr, onLine)]);
1229
+ return {
1230
+ exited: logcat.exited.then(async (code) => {
1231
+ await logs;
1232
+ for (const port of reverse) await exec([...adb, "reverse", "--remove", `tcp:${port}`], { echo: false });
1233
+ return code;
1234
+ }),
1235
+ stop: () => logcat.kill("SIGTERM"),
1236
+ device: await describeSerial(tools.adb, serial, serial.startsWith("emulator-") ? "booted" : "connected"),
1237
+ };
1238
+ }
1239
+
1240
+ export async function runAndroid(ctx: BuildContext, apk: string, args: ParsedArgs): Promise<number> {
1241
+ const app = await launchAndroid(ctx, apk, {
1242
+ env: envFromProcess(),
1243
+ headless: args.flags.headless === true,
1244
+ avd: typeof args.flags.avd === "string" ? args.flags.avd : undefined,
1245
+ device: typeof args.flags.device === "string" ? args.flags.device : undefined,
1246
+ });
1247
+ log.ok(`running ${androidAppId(ctx)}, logs below. Ctrl+C to stop following.`);
1248
+ return follow(app);
1249
+ }
1250
+
1251
+ /** Fails the build when compiled code reaches a framework API above minSdk outside an ApiN class (lib/apilevel.ts). */
1252
+ function checkApis(jar: string, plugins: NativePlugin<AndroidManifest>[], androidJar: string): void {
1253
+ const xml = apiVersionsFor(androidJar);
1254
+ if (!xml) {
1255
+ log.warn(`no data/api-versions.xml next to ${androidJar}: API levels are not checked`);
1256
+ return;
1257
+ }
1258
+ const packageLevels = plugins.map(({ plugin, native }): [string, number] => [
1259
+ native.class.slice(0, native.class.lastIndexOf(".") + 1).replace(/\./g, "/"),
1260
+ pluginMinSdk(plugin.manifest.id, native, MIN_SDK, TOOLCHAIN.android.compileSdk),
1261
+ ]);
1262
+ const problems = checkApiLevels(new Uint8Array(readFileSync(jar)), loadApiVersions(xml), MIN_SDK, packageLevels);
1263
+ if (problems.length) throw new CliError(formatApiProblems(problems, MIN_SDK));
1264
+ }
1265
+
1266
+ /**
1267
+ * `akan-native plugin compile android`: compiles the shell, these plugins and their generated bindings
1268
+ * with a registry of just them, in a fresh temporary folder (so several checks can run at once).
1269
+ */
1270
+ export async function compileAndroidPlugins(
1271
+ plugins: NativePlugin<AndroidManifest>[],
1272
+ appDir: string,
1273
+ ): Promise<ExecResult> {
1274
+ const tools = androidTools();
1275
+ const java = await javaToolchain();
1276
+ const dir = mkdtempSync(join(tmpdir(), "akan-native-compile-android-"));
1277
+ try {
1278
+ const registry = join(dir, "kotlin", "com", "akanjs", "generated", "AkanNativeGeneratedPlugins.kt");
1279
+ mkdirSync(dirname(registry), { recursive: true });
1280
+ writeFileSync(registry, kotlinRegistry(plugins, MIN_SDK, TOOLCHAIN.android.compileSdk));
1281
+ const vectorData = join(dir, "kotlin", "com", "akanjs", "runtime", "AkanNativeVectorData.kt");
1282
+ mkdirSync(dirname(vectorData), { recursive: true });
1283
+ writeFileSync(vectorData, kotlinVectorData(false));
1284
+
1285
+ const features = join(dir, "kotlin", "com", "akanjs", "runtime", "AkanNativeFeatures.kt");
1286
+ writeFileSync(features, kotlinFeatures({ dev: true, updates: true }));
1287
+ const bindings = writePluginBindings(plugins, "android", join(dir, "spec"), appDir);
1288
+ const sources = [
1289
+ ...kotlinSources(SHELL_SRC),
1290
+ ...plugins.flatMap((p) => p.sources),
1291
+ registry,
1292
+ vectorData,
1293
+ features,
1294
+ ...bindings,
1295
+ ];
1296
+ const jar = join(dir, "classes.jar");
1297
+ const libraries = await mavenLibraries(plugins);
1298
+ const classpath = [tools.androidJar, java.kotlin.stdlib, ...libraries.map((l) => l.classes)].join(":");
1299
+ const result = await exec(
1300
+ [
1301
+ java.kotlin.kotlinc,
1302
+ ...sources,
1303
+ "-d",
1304
+ jar,
1305
+ "-classpath",
1306
+ classpath,
1307
+ "-jvm-target",
1308
+ "17",
1309
+ "-no-jdk",
1310
+ "-no-stdlib",
1311
+ "-no-reflect",
1312
+ ],
1313
+ { echo: false, env: java.env },
1314
+ );
1315
+ if (result.code === 0) checkApis(jar, plugins, tools.androidJar);
1316
+ return result;
1317
+ } finally {
1318
+ rmSync(dir, { recursive: true, force: true });
1319
+ }
1320
+ }