@hubspot/app-connect-sdk 1.0.0-alpha.2 → 1.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (532) hide show
  1. package/.turbo/turbo-tsdown.log +41 -510
  2. package/build/tsconfig.browser.tsbuildinfo +1 -1
  3. package/build/tsconfig.server.tsbuildinfo +1 -1
  4. package/dist/browser/{HubSpotAppConnect-BW45gyDs.js → HubSpotAppConnect-COQgPrFn.js} +5 -3
  5. package/dist/browser/HubSpotAppConnect-COQgPrFn.js.map +1 -0
  6. package/dist/browser/{create-vctOhpX9.js → create-hzqjIhmO.js} +54 -25
  7. package/dist/browser/create-hzqjIhmO.js.map +1 -0
  8. package/dist/browser/index.js +1 -1
  9. package/dist/browser/react/lovable.js +2 -2
  10. package/dist/browser/react.js +1 -1
  11. package/dist/server/api-client.d.ts +60625 -197
  12. package/dist/server/api-client.js +5826 -100
  13. package/dist/server/api-client.js.map +1 -0
  14. package/dist/server/{api-client-core/client.js → binary-data-BOalJzKu.js} +58 -3
  15. package/dist/server/binary-data-BOalJzKu.js.map +1 -0
  16. package/dist/server/lovable.d.ts +117 -6
  17. package/dist/server/lovable.js +1458 -3
  18. package/dist/server/lovable.js.map +1 -0
  19. package/dist/server/oauth.d.ts +128 -6
  20. package/dist/server/oauth.js +1 -4
  21. package/dist/server/sha256-B7y8GBFB.js +228 -0
  22. package/dist/server/sha256-B7y8GBFB.js.map +1 -0
  23. package/dist/server/{types.d.ts → types-5gfN91Fq.d.ts} +2 -2
  24. package/dist/server/{api-client-core/types.d.ts → types-DEOUH4wE.d.ts} +2 -2
  25. package/package.json +4 -10
  26. package/src/browser/app-connect-controller/connect-start.ts +2 -1
  27. package/src/browser/app-connect-controller/init.test.ts +167 -0
  28. package/src/browser/app-connect-controller/init.ts +70 -19
  29. package/src/browser/react/components/AppConnectHeader/AppConnectHeader.tsx +3 -5
  30. package/src/browser/react/components/ConnectButton/ConnectButton.tsx +2 -1
  31. package/src/server/api-client-core/plugins/fetch-transport.ts +5 -1
  32. package/src/server/constants.ts +29 -4
  33. package/src/server/hono/hono-request-handler.ts +42 -15
  34. package/src/server/hono/hubspot-connect-routes/auth-complete.test.ts +285 -0
  35. package/src/server/hono/hubspot-connect-routes/{auth-callback.ts → auth-complete.ts} +73 -30
  36. package/src/server/hono/hubspot-connect-routes/auth-init-session.test.ts +114 -30
  37. package/src/server/hono/hubspot-connect-routes/auth-init-session.ts +33 -10
  38. package/src/server/hono/hubspot-connect-routes/auth-logout.test.ts +13 -0
  39. package/src/server/hono/hubspot-connect-routes/auth-logout.ts +18 -0
  40. package/src/server/hono/hubspot-connect-routes/auth-refresh.test.ts +6 -0
  41. package/src/server/hono/hubspot-connect-routes/auth-refresh.ts +6 -0
  42. package/src/server/hono/hubspot-connect-routes/hubspot-connect-routes.ts +9 -2
  43. package/src/server/hono/hubspot-connect-routes/utils.ts +57 -1
  44. package/src/server/hono/types.ts +15 -9
  45. package/src/server/hono/utils/cookie-utils.ts +27 -2
  46. package/src/server/hono/utils/cors-middleware.test.ts +79 -0
  47. package/src/server/hono/utils/cors-middleware.ts +95 -0
  48. package/src/server/sanitize-request.ts +25 -11
  49. package/src/server/types.ts +2 -2
  50. package/src/shared/constants.ts +31 -3
  51. package/src/shared/wire-types.ts +19 -0
  52. package/tsdown.config.ts +1 -1
  53. package/.turbo/turbo-format$colon$check.log +0 -4
  54. package/.turbo/turbo-lint.log +0 -2
  55. package/.turbo/turbo-test.log +0 -76
  56. package/dist/browser/HubSpotAppConnect-BW45gyDs.js.map +0 -1
  57. package/dist/browser/create-vctOhpX9.js.map +0 -1
  58. package/dist/server/api-client-core/apis/account/account-info-types.generated.d.ts +0 -111
  59. package/dist/server/api-client-core/apis/account/account-info.generated.d.ts +0 -7
  60. package/dist/server/api-client-core/apis/account/account-info.generated.js +0 -9
  61. package/dist/server/api-client-core/apis/account/account-info.generated.js.map +0 -1
  62. package/dist/server/api-client-core/apis/account/audit-logs-types.generated.d.ts +0 -247
  63. package/dist/server/api-client-core/apis/account/audit-logs.generated.d.ts +0 -7
  64. package/dist/server/api-client-core/apis/account/audit-logs.generated.js +0 -28
  65. package/dist/server/api-client-core/apis/account/audit-logs.generated.js.map +0 -1
  66. package/dist/server/api-client-core/apis/auth/oauth-types.generated.d.ts +0 -121
  67. package/dist/server/api-client-core/apis/auth/oauth.generated.d.ts +0 -7
  68. package/dist/server/api-client-core/apis/auth/oauth.generated.js +0 -19
  69. package/dist/server/api-client-core/apis/auth/oauth.generated.js.map +0 -1
  70. package/dist/server/api-client-core/apis/automation/actions-types.generated.d.ts +0 -933
  71. package/dist/server/api-client-core/apis/automation/actions.generated.d.ts +0 -7
  72. package/dist/server/api-client-core/apis/automation/actions.generated.js +0 -121
  73. package/dist/server/api-client-core/apis/automation/actions.generated.js.map +0 -1
  74. package/dist/server/api-client-core/apis/automation/sequences-types.generated.d.ts +0 -422
  75. package/dist/server/api-client-core/apis/automation/sequences.generated.d.ts +0 -7
  76. package/dist/server/api-client-core/apis/automation/sequences.generated.js +0 -22
  77. package/dist/server/api-client-core/apis/automation/sequences.generated.js.map +0 -1
  78. package/dist/server/api-client-core/apis/business-units-types.generated.d.ts +0 -75
  79. package/dist/server/api-client-core/apis/business-units.generated.d.ts +0 -7
  80. package/dist/server/api-client-core/apis/business-units.generated.js +0 -12
  81. package/dist/server/api-client-core/apis/business-units.generated.js.map +0 -1
  82. package/dist/server/api-client-core/apis/cms/authors-types.generated.d.ts +0 -551
  83. package/dist/server/api-client-core/apis/cms/authors.generated.d.ts +0 -7
  84. package/dist/server/api-client-core/apis/cms/authors.generated.js +0 -163
  85. package/dist/server/api-client-core/apis/cms/authors.generated.js.map +0 -1
  86. package/dist/server/api-client-core/apis/cms/blog-settings-types.generated.d.ts +0 -366
  87. package/dist/server/api-client-core/apis/cms/blog-settings.generated.d.ts +0 -7
  88. package/dist/server/api-client-core/apis/cms/blog-settings.generated.js +0 -43
  89. package/dist/server/api-client-core/apis/cms/blog-settings.generated.js.map +0 -1
  90. package/dist/server/api-client-core/apis/cms/cms-content-audit-types.generated.d.ts +0 -157
  91. package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.d.ts +0 -7
  92. package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.js +0 -18
  93. package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.js.map +0 -1
  94. package/dist/server/api-client-core/apis/cms/domains-types.generated.d.ts +0 -193
  95. package/dist/server/api-client-core/apis/cms/domains.generated.d.ts +0 -7
  96. package/dist/server/api-client-core/apis/cms/domains.generated.js +0 -20
  97. package/dist/server/api-client-core/apis/cms/domains.generated.js.map +0 -1
  98. package/dist/server/api-client-core/apis/cms/hubdb-types.generated.d.ts +0 -1097
  99. package/dist/server/api-client-core/apis/cms/hubdb.generated.d.ts +0 -7
  100. package/dist/server/api-client-core/apis/cms/hubdb.generated.js +0 -192
  101. package/dist/server/api-client-core/apis/cms/hubdb.generated.js.map +0 -1
  102. package/dist/server/api-client-core/apis/cms/media-bridge-types.generated.d.ts +0 -1780
  103. package/dist/server/api-client-core/apis/cms/media-bridge.generated.d.ts +0 -7
  104. package/dist/server/api-client-core/apis/cms/media-bridge.generated.js +0 -185
  105. package/dist/server/api-client-core/apis/cms/media-bridge.generated.js.map +0 -1
  106. package/dist/server/api-client-core/apis/cms/pages-types.generated.d.ts +0 -1768
  107. package/dist/server/api-client-core/apis/cms/pages.generated.d.ts +0 -7
  108. package/dist/server/api-client-core/apis/cms/pages.generated.js +0 -331
  109. package/dist/server/api-client-core/apis/cms/pages.generated.js.map +0 -1
  110. package/dist/server/api-client-core/apis/cms/posts-types.generated.d.ts +0 -1090
  111. package/dist/server/api-client-core/apis/cms/posts.generated.d.ts +0 -7
  112. package/dist/server/api-client-core/apis/cms/posts.generated.js +0 -201
  113. package/dist/server/api-client-core/apis/cms/posts.generated.js.map +0 -1
  114. package/dist/server/api-client-core/apis/cms/site-search-types.generated.d.ts +0 -200
  115. package/dist/server/api-client-core/apis/cms/site-search.generated.d.ts +0 -7
  116. package/dist/server/api-client-core/apis/cms/site-search.generated.js +0 -32
  117. package/dist/server/api-client-core/apis/cms/site-search.generated.js.map +0 -1
  118. package/dist/server/api-client-core/apis/cms/source-code-types.generated.d.ts +0 -218
  119. package/dist/server/api-client-core/apis/cms/source-code.generated.d.ts +0 -7
  120. package/dist/server/api-client-core/apis/cms/source-code.generated.js +0 -52
  121. package/dist/server/api-client-core/apis/cms/source-code.generated.js.map +0 -1
  122. package/dist/server/api-client-core/apis/cms/tags-types.generated.d.ts +0 -515
  123. package/dist/server/api-client-core/apis/cms/tags.generated.d.ts +0 -7
  124. package/dist/server/api-client-core/apis/cms/tags.generated.js +0 -163
  125. package/dist/server/api-client-core/apis/cms/tags.generated.js.map +0 -1
  126. package/dist/server/api-client-core/apis/cms/url-mappings-types.generated.d.ts +0 -177
  127. package/dist/server/api-client-core/apis/cms/url-mappings.generated.d.ts +0 -7
  128. package/dist/server/api-client-core/apis/cms/url-mappings.generated.js +0 -14
  129. package/dist/server/api-client-core/apis/cms/url-mappings.generated.js.map +0 -1
  130. package/dist/server/api-client-core/apis/cms/url-redirects-types.generated.d.ts +0 -226
  131. package/dist/server/api-client-core/apis/cms/url-redirects.generated.d.ts +0 -7
  132. package/dist/server/api-client-core/apis/cms/url-redirects.generated.js +0 -26
  133. package/dist/server/api-client-core/apis/cms/url-redirects.generated.js.map +0 -1
  134. package/dist/server/api-client-core/apis/communication-preferences/subscriptions-types.generated.d.ts +0 -802
  135. package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.d.ts +0 -7
  136. package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.js +0 -74
  137. package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.js.map +0 -1
  138. package/dist/server/api-client-core/apis/conversations/custom-channels-types.generated.d.ts +0 -551
  139. package/dist/server/api-client-core/apis/conversations/custom-channels.generated.d.ts +0 -7
  140. package/dist/server/api-client-core/apis/conversations/custom-channels.generated.js +0 -80
  141. package/dist/server/api-client-core/apis/conversations/custom-channels.generated.js.map +0 -1
  142. package/dist/server/api-client-core/apis/conversations/visitor-identification-types.generated.d.ts +0 -60
  143. package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.d.ts +0 -7
  144. package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.js +0 -6
  145. package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.js.map +0 -1
  146. package/dist/server/api-client-core/apis/conversations-types.generated.d.ts +0 -908
  147. package/dist/server/api-client-core/apis/conversations.generated.d.ts +0 -7
  148. package/dist/server/api-client-core/apis/conversations.generated.js +0 -108
  149. package/dist/server/api-client-core/apis/conversations.generated.js.map +0 -1
  150. package/dist/server/api-client-core/apis/crm/app-uninstalls-types.generated.d.ts +0 -37
  151. package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.d.ts +0 -7
  152. package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.js +0 -6
  153. package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.js.map +0 -1
  154. package/dist/server/api-client-core/apis/crm/appointments-types.generated.d.ts +0 -989
  155. package/dist/server/api-client-core/apis/crm/appointments.generated.d.ts +0 -7
  156. package/dist/server/api-client-core/apis/crm/appointments.generated.js +0 -118
  157. package/dist/server/api-client-core/apis/crm/appointments.generated.js.map +0 -1
  158. package/dist/server/api-client-core/apis/crm/associations-schema-types.generated.d.ts +0 -329
  159. package/dist/server/api-client-core/apis/crm/associations-schema.generated.d.ts +0 -7
  160. package/dist/server/api-client-core/apis/crm/associations-schema.generated.js +0 -60
  161. package/dist/server/api-client-core/apis/crm/associations-schema.generated.js.map +0 -1
  162. package/dist/server/api-client-core/apis/crm/associations-types.generated.d.ts +0 -661
  163. package/dist/server/api-client-core/apis/crm/associations.generated.d.ts +0 -7
  164. package/dist/server/api-client-core/apis/crm/associations.generated.js +0 -83
  165. package/dist/server/api-client-core/apis/crm/associations.generated.js.map +0 -1
  166. package/dist/server/api-client-core/apis/crm/calling-extensions-types.generated.d.ts +0 -466
  167. package/dist/server/api-client-core/apis/crm/calling-extensions.generated.d.ts +0 -7
  168. package/dist/server/api-client-core/apis/crm/calling-extensions.generated.js +0 -42
  169. package/dist/server/api-client-core/apis/crm/calling-extensions.generated.js.map +0 -1
  170. package/dist/server/api-client-core/apis/crm/calls-types.generated.d.ts +0 -850
  171. package/dist/server/api-client-core/apis/crm/calls.generated.d.ts +0 -7
  172. package/dist/server/api-client-core/apis/crm/calls.generated.js +0 -66
  173. package/dist/server/api-client-core/apis/crm/calls.generated.js.map +0 -1
  174. package/dist/server/api-client-core/apis/crm/carts-types.generated.d.ts +0 -850
  175. package/dist/server/api-client-core/apis/crm/carts.generated.d.ts +0 -7
  176. package/dist/server/api-client-core/apis/crm/carts.generated.js +0 -66
  177. package/dist/server/api-client-core/apis/crm/carts.generated.js.map +0 -1
  178. package/dist/server/api-client-core/apis/crm/commerce-payments-types.generated.d.ts +0 -850
  179. package/dist/server/api-client-core/apis/crm/commerce-payments.generated.d.ts +0 -7
  180. package/dist/server/api-client-core/apis/crm/commerce-payments.generated.js +0 -66
  181. package/dist/server/api-client-core/apis/crm/commerce-payments.generated.js.map +0 -1
  182. package/dist/server/api-client-core/apis/crm/commerce-subscriptions-types.generated.d.ts +0 -847
  183. package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.d.ts +0 -7
  184. package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.js +0 -66
  185. package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.js.map +0 -1
  186. package/dist/server/api-client-core/apis/crm/communications-types.generated.d.ts +0 -850
  187. package/dist/server/api-client-core/apis/crm/communications.generated.d.ts +0 -7
  188. package/dist/server/api-client-core/apis/crm/communications.generated.js +0 -66
  189. package/dist/server/api-client-core/apis/crm/communications.generated.js.map +0 -1
  190. package/dist/server/api-client-core/apis/crm/companies-types.generated.d.ts +0 -884
  191. package/dist/server/api-client-core/apis/crm/companies.generated.d.ts +0 -7
  192. package/dist/server/api-client-core/apis/crm/companies.generated.js +0 -67
  193. package/dist/server/api-client-core/apis/crm/companies.generated.js.map +0 -1
  194. package/dist/server/api-client-core/apis/crm/contacts-types.generated.d.ts +0 -899
  195. package/dist/server/api-client-core/apis/crm/contacts.generated.d.ts +0 -7
  196. package/dist/server/api-client-core/apis/crm/contacts.generated.js +0 -70
  197. package/dist/server/api-client-core/apis/crm/contacts.generated.js.map +0 -1
  198. package/dist/server/api-client-core/apis/crm/contracts-types.generated.d.ts +0 -850
  199. package/dist/server/api-client-core/apis/crm/contracts.generated.d.ts +0 -7
  200. package/dist/server/api-client-core/apis/crm/contracts.generated.js +0 -66
  201. package/dist/server/api-client-core/apis/crm/contracts.generated.js.map +0 -1
  202. package/dist/server/api-client-core/apis/crm/courses-types.generated.d.ts +0 -853
  203. package/dist/server/api-client-core/apis/crm/courses.generated.d.ts +0 -7
  204. package/dist/server/api-client-core/apis/crm/courses.generated.js +0 -66
  205. package/dist/server/api-client-core/apis/crm/courses.generated.js.map +0 -1
  206. package/dist/server/api-client-core/apis/crm/crm-owners-types.generated.d.ts +0 -140
  207. package/dist/server/api-client-core/apis/crm/crm-owners.generated.d.ts +0 -7
  208. package/dist/server/api-client-core/apis/crm/crm-owners.generated.js +0 -20
  209. package/dist/server/api-client-core/apis/crm/crm-owners.generated.js.map +0 -1
  210. package/dist/server/api-client-core/apis/crm/custom-objects-types.generated.d.ts +0 -934
  211. package/dist/server/api-client-core/apis/crm/custom-objects.generated.d.ts +0 -7
  212. package/dist/server/api-client-core/apis/crm/custom-objects.generated.js +0 -101
  213. package/dist/server/api-client-core/apis/crm/custom-objects.generated.js.map +0 -1
  214. package/dist/server/api-client-core/apis/crm/deal-splits-types.generated.d.ts +0 -196
  215. package/dist/server/api-client-core/apis/crm/deal-splits.generated.d.ts +0 -7
  216. package/dist/server/api-client-core/apis/crm/deal-splits.generated.js +0 -9
  217. package/dist/server/api-client-core/apis/crm/deal-splits.generated.js.map +0 -1
  218. package/dist/server/api-client-core/apis/crm/deals-types.generated.d.ts +0 -872
  219. package/dist/server/api-client-core/apis/crm/deals.generated.d.ts +0 -7
  220. package/dist/server/api-client-core/apis/crm/deals.generated.js +0 -67
  221. package/dist/server/api-client-core/apis/crm/deals.generated.js.map +0 -1
  222. package/dist/server/api-client-core/apis/crm/discounts-types.generated.d.ts +0 -846
  223. package/dist/server/api-client-core/apis/crm/discounts.generated.d.ts +0 -7
  224. package/dist/server/api-client-core/apis/crm/discounts.generated.js +0 -66
  225. package/dist/server/api-client-core/apis/crm/discounts.generated.js.map +0 -1
  226. package/dist/server/api-client-core/apis/crm/emails-types.generated.d.ts +0 -850
  227. package/dist/server/api-client-core/apis/crm/emails.generated.d.ts +0 -7
  228. package/dist/server/api-client-core/apis/crm/emails.generated.js +0 -66
  229. package/dist/server/api-client-core/apis/crm/emails.generated.js.map +0 -1
  230. package/dist/server/api-client-core/apis/crm/exports-types.generated.d.ts +0 -281
  231. package/dist/server/api-client-core/apis/crm/exports.generated.d.ts +0 -7
  232. package/dist/server/api-client-core/apis/crm/exports.generated.js +0 -12
  233. package/dist/server/api-client-core/apis/crm/exports.generated.js.map +0 -1
  234. package/dist/server/api-client-core/apis/crm/feedback-submissions-types.generated.d.ts +0 -616
  235. package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.d.ts +0 -7
  236. package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.js +0 -55
  237. package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.js.map +0 -1
  238. package/dist/server/api-client-core/apis/crm/fees-types.generated.d.ts +0 -850
  239. package/dist/server/api-client-core/apis/crm/fees.generated.d.ts +0 -7
  240. package/dist/server/api-client-core/apis/crm/fees.generated.js +0 -66
  241. package/dist/server/api-client-core/apis/crm/fees.generated.js.map +0 -1
  242. package/dist/server/api-client-core/apis/crm/goal-targets-types.generated.d.ts +0 -850
  243. package/dist/server/api-client-core/apis/crm/goal-targets.generated.d.ts +0 -7
  244. package/dist/server/api-client-core/apis/crm/goal-targets.generated.js +0 -66
  245. package/dist/server/api-client-core/apis/crm/goal-targets.generated.js.map +0 -1
  246. package/dist/server/api-client-core/apis/crm/imports-types.generated.d.ts +0 -371
  247. package/dist/server/api-client-core/apis/crm/imports.generated.d.ts +0 -7
  248. package/dist/server/api-client-core/apis/crm/imports.generated.js +0 -30
  249. package/dist/server/api-client-core/apis/crm/imports.generated.js.map +0 -1
  250. package/dist/server/api-client-core/apis/crm/invoices-types.generated.d.ts +0 -850
  251. package/dist/server/api-client-core/apis/crm/invoices.generated.d.ts +0 -7
  252. package/dist/server/api-client-core/apis/crm/invoices.generated.js +0 -66
  253. package/dist/server/api-client-core/apis/crm/invoices.generated.js.map +0 -1
  254. package/dist/server/api-client-core/apis/crm/leads-types.generated.d.ts +0 -850
  255. package/dist/server/api-client-core/apis/crm/leads.generated.d.ts +0 -7
  256. package/dist/server/api-client-core/apis/crm/leads.generated.js +0 -66
  257. package/dist/server/api-client-core/apis/crm/leads.generated.js.map +0 -1
  258. package/dist/server/api-client-core/apis/crm/limits-tracking-types.generated.d.ts +0 -331
  259. package/dist/server/api-client-core/apis/crm/limits-tracking.generated.d.ts +0 -7
  260. package/dist/server/api-client-core/apis/crm/limits-tracking.generated.js +0 -22
  261. package/dist/server/api-client-core/apis/crm/limits-tracking.generated.js.map +0 -1
  262. package/dist/server/api-client-core/apis/crm/line-items-types.generated.d.ts +0 -850
  263. package/dist/server/api-client-core/apis/crm/line-items.generated.d.ts +0 -7
  264. package/dist/server/api-client-core/apis/crm/line-items.generated.js +0 -66
  265. package/dist/server/api-client-core/apis/crm/line-items.generated.js.map +0 -1
  266. package/dist/server/api-client-core/apis/crm/listings-types.generated.d.ts +0 -853
  267. package/dist/server/api-client-core/apis/crm/listings.generated.d.ts +0 -7
  268. package/dist/server/api-client-core/apis/crm/listings.generated.js +0 -66
  269. package/dist/server/api-client-core/apis/crm/listings.generated.js.map +0 -1
  270. package/dist/server/api-client-core/apis/crm/lists-types.generated.d.ts +0 -2265
  271. package/dist/server/api-client-core/apis/crm/lists.generated.d.ts +0 -7
  272. package/dist/server/api-client-core/apis/crm/lists.generated.js +0 -105
  273. package/dist/server/api-client-core/apis/crm/lists.generated.js.map +0 -1
  274. package/dist/server/api-client-core/apis/crm/meetings-types.generated.d.ts +0 -850
  275. package/dist/server/api-client-core/apis/crm/meetings.generated.d.ts +0 -7
  276. package/dist/server/api-client-core/apis/crm/meetings.generated.js +0 -66
  277. package/dist/server/api-client-core/apis/crm/meetings.generated.js.map +0 -1
  278. package/dist/server/api-client-core/apis/crm/notes-types.generated.d.ts +0 -850
  279. package/dist/server/api-client-core/apis/crm/notes.generated.d.ts +0 -7
  280. package/dist/server/api-client-core/apis/crm/notes.generated.js +0 -66
  281. package/dist/server/api-client-core/apis/crm/notes.generated.js.map +0 -1
  282. package/dist/server/api-client-core/apis/crm/object-library-types.generated.d.ts +0 -60
  283. package/dist/server/api-client-core/apis/crm/object-library.generated.d.ts +0 -7
  284. package/dist/server/api-client-core/apis/crm/object-library.generated.js +0 -9
  285. package/dist/server/api-client-core/apis/crm/object-library.generated.js.map +0 -1
  286. package/dist/server/api-client-core/apis/crm/objects-types.generated.d.ts +0 -712
  287. package/dist/server/api-client-core/apis/crm/objects.generated.d.ts +0 -7
  288. package/dist/server/api-client-core/apis/crm/objects.generated.js +0 -76
  289. package/dist/server/api-client-core/apis/crm/objects.generated.js.map +0 -1
  290. package/dist/server/api-client-core/apis/crm/orders-types.generated.d.ts +0 -850
  291. package/dist/server/api-client-core/apis/crm/orders.generated.d.ts +0 -7
  292. package/dist/server/api-client-core/apis/crm/orders.generated.js +0 -66
  293. package/dist/server/api-client-core/apis/crm/orders.generated.js.map +0 -1
  294. package/dist/server/api-client-core/apis/crm/partner-clients-types.generated.d.ts +0 -725
  295. package/dist/server/api-client-core/apis/crm/partner-clients.generated.d.ts +0 -7
  296. package/dist/server/api-client-core/apis/crm/partner-clients.generated.js +0 -71
  297. package/dist/server/api-client-core/apis/crm/partner-clients.generated.js.map +0 -1
  298. package/dist/server/api-client-core/apis/crm/partner-services-types.generated.d.ts +0 -725
  299. package/dist/server/api-client-core/apis/crm/partner-services.generated.d.ts +0 -7
  300. package/dist/server/api-client-core/apis/crm/partner-services.generated.js +0 -71
  301. package/dist/server/api-client-core/apis/crm/partner-services.generated.js.map +0 -1
  302. package/dist/server/api-client-core/apis/crm/pipelines-types.generated.d.ts +0 -430
  303. package/dist/server/api-client-core/apis/crm/pipelines.generated.d.ts +0 -7
  304. package/dist/server/api-client-core/apis/crm/pipelines.generated.js +0 -94
  305. package/dist/server/api-client-core/apis/crm/pipelines.generated.js.map +0 -1
  306. package/dist/server/api-client-core/apis/crm/postal-mail-types.generated.d.ts +0 -844
  307. package/dist/server/api-client-core/apis/crm/postal-mail.generated.d.ts +0 -7
  308. package/dist/server/api-client-core/apis/crm/postal-mail.generated.js +0 -66
  309. package/dist/server/api-client-core/apis/crm/postal-mail.generated.js.map +0 -1
  310. package/dist/server/api-client-core/apis/crm/products-types.generated.d.ts +0 -850
  311. package/dist/server/api-client-core/apis/crm/products.generated.d.ts +0 -7
  312. package/dist/server/api-client-core/apis/crm/products.generated.js +0 -66
  313. package/dist/server/api-client-core/apis/crm/products.generated.js.map +0 -1
  314. package/dist/server/api-client-core/apis/crm/projects-types.generated.d.ts +0 -881
  315. package/dist/server/api-client-core/apis/crm/projects.generated.d.ts +0 -7
  316. package/dist/server/api-client-core/apis/crm/projects.generated.js +0 -67
  317. package/dist/server/api-client-core/apis/crm/projects.generated.js.map +0 -1
  318. package/dist/server/api-client-core/apis/crm/properties-types.generated.d.ts +0 -603
  319. package/dist/server/api-client-core/apis/crm/properties.generated.d.ts +0 -7
  320. package/dist/server/api-client-core/apis/crm/properties.generated.js +0 -86
  321. package/dist/server/api-client-core/apis/crm/properties.generated.js.map +0 -1
  322. package/dist/server/api-client-core/apis/crm/property-validations-types.generated.d.ts +0 -121
  323. package/dist/server/api-client-core/apis/crm/property-validations.generated.d.ts +0 -7
  324. package/dist/server/api-client-core/apis/crm/property-validations.generated.js +0 -25
  325. package/dist/server/api-client-core/apis/crm/property-validations.generated.js.map +0 -1
  326. package/dist/server/api-client-core/apis/crm/public-app-crm-cards-types.generated.d.ts +0 -486
  327. package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.d.ts +0 -7
  328. package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.js +0 -34
  329. package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.js.map +0 -1
  330. package/dist/server/api-client-core/apis/crm/public-app-feature-flags-types.generated.d.ts +0 -247
  331. package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.d.ts +0 -7
  332. package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.js +0 -69
  333. package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.js.map +0 -1
  334. package/dist/server/api-client-core/apis/crm/quotes-types.generated.d.ts +0 -850
  335. package/dist/server/api-client-core/apis/crm/quotes.generated.d.ts +0 -7
  336. package/dist/server/api-client-core/apis/crm/quotes.generated.js +0 -66
  337. package/dist/server/api-client-core/apis/crm/quotes.generated.js.map +0 -1
  338. package/dist/server/api-client-core/apis/crm/schemas-types.generated.d.ts +0 -669
  339. package/dist/server/api-client-core/apis/crm/schemas.generated.d.ts +0 -7
  340. package/dist/server/api-client-core/apis/crm/schemas.generated.js +0 -41
  341. package/dist/server/api-client-core/apis/crm/schemas.generated.js.map +0 -1
  342. package/dist/server/api-client-core/apis/crm/services-types.generated.d.ts +0 -853
  343. package/dist/server/api-client-core/apis/crm/services.generated.d.ts +0 -7
  344. package/dist/server/api-client-core/apis/crm/services.generated.js +0 -66
  345. package/dist/server/api-client-core/apis/crm/services.generated.js.map +0 -1
  346. package/dist/server/api-client-core/apis/crm/tasks-types.generated.d.ts +0 -850
  347. package/dist/server/api-client-core/apis/crm/tasks.generated.d.ts +0 -7
  348. package/dist/server/api-client-core/apis/crm/tasks.generated.js +0 -66
  349. package/dist/server/api-client-core/apis/crm/tasks.generated.js.map +0 -1
  350. package/dist/server/api-client-core/apis/crm/taxes-types.generated.d.ts +0 -850
  351. package/dist/server/api-client-core/apis/crm/taxes.generated.d.ts +0 -7
  352. package/dist/server/api-client-core/apis/crm/taxes.generated.js +0 -66
  353. package/dist/server/api-client-core/apis/crm/taxes.generated.js.map +0 -1
  354. package/dist/server/api-client-core/apis/crm/tickets-types.generated.d.ts +0 -884
  355. package/dist/server/api-client-core/apis/crm/tickets.generated.d.ts +0 -7
  356. package/dist/server/api-client-core/apis/crm/tickets.generated.js +0 -67
  357. package/dist/server/api-client-core/apis/crm/tickets.generated.js.map +0 -1
  358. package/dist/server/api-client-core/apis/crm/timeline-types.generated.d.ts +0 -187
  359. package/dist/server/api-client-core/apis/crm/timeline.generated.d.ts +0 -7
  360. package/dist/server/api-client-core/apis/crm/timeline.generated.js +0 -12
  361. package/dist/server/api-client-core/apis/crm/timeline.generated.js.map +0 -1
  362. package/dist/server/api-client-core/apis/crm/transcriptions-types.generated.d.ts +0 -152
  363. package/dist/server/api-client-core/apis/crm/transcriptions.generated.d.ts +0 -7
  364. package/dist/server/api-client-core/apis/crm/transcriptions.generated.js +0 -15
  365. package/dist/server/api-client-core/apis/crm/transcriptions.generated.js.map +0 -1
  366. package/dist/server/api-client-core/apis/crm/users-types.generated.d.ts +0 -850
  367. package/dist/server/api-client-core/apis/crm/users.generated.d.ts +0 -7
  368. package/dist/server/api-client-core/apis/crm/users.generated.js +0 -66
  369. package/dist/server/api-client-core/apis/crm/users.generated.js.map +0 -1
  370. package/dist/server/api-client-core/apis/crm/video-conferencing-extension-types.generated.d.ts +0 -72
  371. package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.d.ts +0 -7
  372. package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.js +0 -13
  373. package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.js.map +0 -1
  374. package/dist/server/api-client-core/apis/events/manage-event-definitions-types.generated.d.ts +0 -1005
  375. package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.d.ts +0 -7
  376. package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.js +0 -39
  377. package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.js.map +0 -1
  378. package/dist/server/api-client-core/apis/events/send-event-completions-types.generated.d.ts +0 -94
  379. package/dist/server/api-client-core/apis/events/send-event-completions.generated.d.ts +0 -7
  380. package/dist/server/api-client-core/apis/events/send-event-completions.generated.js +0 -9
  381. package/dist/server/api-client-core/apis/events/send-event-completions.generated.js.map +0 -1
  382. package/dist/server/api-client-core/apis/events-types.generated.d.ts +0 -137
  383. package/dist/server/api-client-core/apis/events.generated.d.ts +0 -7
  384. package/dist/server/api-client-core/apis/events.generated.js +0 -23
  385. package/dist/server/api-client-core/apis/events.generated.js.map +0 -1
  386. package/dist/server/api-client-core/apis/files-types.generated.d.ts +0 -791
  387. package/dist/server/api-client-core/apis/files.generated.d.ts +0 -7
  388. package/dist/server/api-client-core/apis/files.generated.js +0 -119
  389. package/dist/server/api-client-core/apis/files.generated.js.map +0 -1
  390. package/dist/server/api-client-core/apis/marketing/campaigns-public-api-types.generated.d.ts +0 -989
  391. package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.d.ts +0 -7
  392. package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.js +0 -139
  393. package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.js.map +0 -1
  394. package/dist/server/api-client-core/apis/marketing/marketing-emails-types.generated.d.ts +0 -883
  395. package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.d.ts +0 -7
  396. package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.js +0 -108
  397. package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.js.map +0 -1
  398. package/dist/server/api-client-core/apis/marketing/marketing-events-types.generated.d.ts +0 -1788
  399. package/dist/server/api-client-core/apis/marketing/marketing-events.generated.d.ts +0 -7
  400. package/dist/server/api-client-core/apis/marketing/marketing-events.generated.js +0 -176
  401. package/dist/server/api-client-core/apis/marketing/marketing-events.generated.js.map +0 -1
  402. package/dist/server/api-client-core/apis/marketing/single-send-types.generated.d.ts +0 -123
  403. package/dist/server/api-client-core/apis/marketing/single-send.generated.d.ts +0 -7
  404. package/dist/server/api-client-core/apis/marketing/single-send.generated.js +0 -6
  405. package/dist/server/api-client-core/apis/marketing/single-send.generated.js.map +0 -1
  406. package/dist/server/api-client-core/apis/marketing/transactional-single-send-types.generated.d.ts +0 -257
  407. package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.d.ts +0 -7
  408. package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.js +0 -20
  409. package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.js.map +0 -1
  410. package/dist/server/api-client-core/apis/meta/origins-types.generated.d.ts +0 -77
  411. package/dist/server/api-client-core/apis/meta/origins.generated.d.ts +0 -7
  412. package/dist/server/api-client-core/apis/meta/origins.generated.js +0 -15
  413. package/dist/server/api-client-core/apis/meta/origins.generated.js.map +0 -1
  414. package/dist/server/api-client-core/apis/scheduler/meetings-types.generated.d.ts +0 -913
  415. package/dist/server/api-client-core/apis/scheduler/meetings.generated.d.ts +0 -7
  416. package/dist/server/api-client-core/apis/scheduler/meetings.generated.js +0 -34
  417. package/dist/server/api-client-core/apis/scheduler/meetings.generated.js.map +0 -1
  418. package/dist/server/api-client-core/apis/settings/multicurrency-types.generated.d.ts +0 -404
  419. package/dist/server/api-client-core/apis/settings/multicurrency.generated.d.ts +0 -7
  420. package/dist/server/api-client-core/apis/settings/multicurrency.generated.js +0 -38
  421. package/dist/server/api-client-core/apis/settings/multicurrency.generated.js.map +0 -1
  422. package/dist/server/api-client-core/apis/settings/tax-rates-types.generated.d.ts +0 -111
  423. package/dist/server/api-client-core/apis/settings/tax-rates.generated.d.ts +0 -7
  424. package/dist/server/api-client-core/apis/settings/tax-rates.generated.js +0 -13
  425. package/dist/server/api-client-core/apis/settings/tax-rates.generated.js.map +0 -1
  426. package/dist/server/api-client-core/apis/settings/user-provisioning-types.generated.d.ts +0 -297
  427. package/dist/server/api-client-core/apis/settings/user-provisioning.generated.d.ts +0 -7
  428. package/dist/server/api-client-core/apis/settings/user-provisioning.generated.js +0 -31
  429. package/dist/server/api-client-core/apis/settings/user-provisioning.generated.js.map +0 -1
  430. package/dist/server/api-client-core/apis/webhooks-journal-types.generated.d.ts +0 -643
  431. package/dist/server/api-client-core/apis/webhooks-journal.generated.d.ts +0 -7
  432. package/dist/server/api-client-core/apis/webhooks-journal.generated.js +0 -75
  433. package/dist/server/api-client-core/apis/webhooks-journal.generated.js.map +0 -1
  434. package/dist/server/api-client-core/apis/webhooks-types.generated.d.ts +0 -1016
  435. package/dist/server/api-client-core/apis/webhooks.generated.d.ts +0 -7
  436. package/dist/server/api-client-core/apis/webhooks.generated.js +0 -105
  437. package/dist/server/api-client-core/apis/webhooks.generated.js.map +0 -1
  438. package/dist/server/api-client-core/binary-data.d.ts +0 -33
  439. package/dist/server/api-client-core/binary-data.js +0 -29
  440. package/dist/server/api-client-core/binary-data.js.map +0 -1
  441. package/dist/server/api-client-core/client.d.ts +0 -14
  442. package/dist/server/api-client-core/client.js.map +0 -1
  443. package/dist/server/api-client-core/codegen-helpers/file-op-wrappers.js +0 -25
  444. package/dist/server/api-client-core/codegen-helpers/file-op-wrappers.js.map +0 -1
  445. package/dist/server/api-client-core/errors.d.ts +0 -27
  446. package/dist/server/api-client-core/errors.js +0 -33
  447. package/dist/server/api-client-core/errors.js.map +0 -1
  448. package/dist/server/api-client-core/op.d.ts +0 -37
  449. package/dist/server/api-client-core/op.js +0 -44
  450. package/dist/server/api-client-core/op.js.map +0 -1
  451. package/dist/server/api-client-core/pagination.d.ts +0 -60
  452. package/dist/server/api-client-core/pagination.js +0 -103
  453. package/dist/server/api-client-core/pagination.js.map +0 -1
  454. package/dist/server/api-client-core/plugins/fetch-transport.js +0 -72
  455. package/dist/server/api-client-core/plugins/fetch-transport.js.map +0 -1
  456. package/dist/server/constants.js +0 -46
  457. package/dist/server/constants.js.map +0 -1
  458. package/dist/server/deno/start.d.ts +0 -12
  459. package/dist/server/deno/start.js +0 -21
  460. package/dist/server/deno/start.js.map +0 -1
  461. package/dist/server/hono/hono-request-handler.js +0 -54
  462. package/dist/server/hono/hono-request-handler.js.map +0 -1
  463. package/dist/server/hono/hubspot-connect-routes/auth-callback.js +0 -125
  464. package/dist/server/hono/hubspot-connect-routes/auth-callback.js.map +0 -1
  465. package/dist/server/hono/hubspot-connect-routes/auth-init-session.js +0 -90
  466. package/dist/server/hono/hubspot-connect-routes/auth-init-session.js.map +0 -1
  467. package/dist/server/hono/hubspot-connect-routes/auth-logout.js +0 -97
  468. package/dist/server/hono/hubspot-connect-routes/auth-logout.js.map +0 -1
  469. package/dist/server/hono/hubspot-connect-routes/auth-refresh.js +0 -101
  470. package/dist/server/hono/hubspot-connect-routes/auth-refresh.js.map +0 -1
  471. package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.d.ts +0 -16
  472. package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.js +0 -13
  473. package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.js.map +0 -1
  474. package/dist/server/hono/hubspot-connect-routes/cimd-public-routes.js +0 -42
  475. package/dist/server/hono/hubspot-connect-routes/cimd-public-routes.js.map +0 -1
  476. package/dist/server/hono/hubspot-connect-routes/constants.js +0 -8
  477. package/dist/server/hono/hubspot-connect-routes/constants.js.map +0 -1
  478. package/dist/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.js +0 -43
  479. package/dist/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.js.map +0 -1
  480. package/dist/server/hono/hubspot-connect-routes/hubspot-connect-routes.js +0 -35
  481. package/dist/server/hono/hubspot-connect-routes/hubspot-connect-routes.js.map +0 -1
  482. package/dist/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.js +0 -34
  483. package/dist/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.js.map +0 -1
  484. package/dist/server/hono/hubspot-connect-routes/oauth-client.js +0 -104
  485. package/dist/server/hono/hubspot-connect-routes/oauth-client.js.map +0 -1
  486. package/dist/server/hono/hubspot-connect-routes/utils.js +0 -73
  487. package/dist/server/hono/hubspot-connect-routes/utils.js.map +0 -1
  488. package/dist/server/hono/index.js +0 -4
  489. package/dist/server/hono/types.d.ts +0 -28
  490. package/dist/server/hono/utils/cookie-utils.js +0 -29
  491. package/dist/server/hono/utils/cookie-utils.js.map +0 -1
  492. package/dist/server/import-app-keys.js +0 -42
  493. package/dist/server/import-app-keys.js.map +0 -1
  494. package/dist/server/lovable/create-app-function-start.d.ts +0 -26
  495. package/dist/server/lovable/create-app-function-start.js +0 -28
  496. package/dist/server/lovable/create-app-function-start.js.map +0 -1
  497. package/dist/server/lovable/hubspot-connect/index.d.ts +0 -15
  498. package/dist/server/lovable/hubspot-connect/index.js +0 -20
  499. package/dist/server/lovable/hubspot-connect/index.js.map +0 -1
  500. package/dist/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.js +0 -29
  501. package/dist/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.js.map +0 -1
  502. package/dist/server/proxy.js +0 -68
  503. package/dist/server/proxy.js.map +0 -1
  504. package/dist/server/sanitize-request.js +0 -41
  505. package/dist/server/sanitize-request.js.map +0 -1
  506. package/dist/server/secure-start-core.d.ts +0 -23
  507. package/dist/server/secure-start-core.js +0 -28
  508. package/dist/server/secure-start-core.js.map +0 -1
  509. package/dist/server/shared/constants.js +0 -17
  510. package/dist/server/shared/constants.js.map +0 -1
  511. package/dist/server/shared/encoding/base64.js +0 -45
  512. package/dist/server/shared/encoding/base64.js.map +0 -1
  513. package/dist/server/shared/encoding/sha256.d.ts +0 -10
  514. package/dist/server/shared/encoding/sha256.js +0 -15
  515. package/dist/server/shared/encoding/sha256.js.map +0 -1
  516. package/dist/server/shared/logger.d.ts +0 -15
  517. package/dist/server/shared/logger.js +0 -16
  518. package/dist/server/shared/logger.js.map +0 -1
  519. package/dist/server/utils/cookie-utils.js +0 -21
  520. package/dist/server/utils/cookie-utils.js.map +0 -1
  521. package/dist/server/utils/dpop-utils.d.ts +0 -67
  522. package/dist/server/utils/dpop-utils.js +0 -75
  523. package/dist/server/utils/dpop-utils.js.map +0 -1
  524. package/dist/server/utils/env-utils.js +0 -54
  525. package/dist/server/utils/env-utils.js.map +0 -1
  526. package/dist/server/utils/jwk-utils.d.ts +0 -16
  527. package/dist/server/utils/jwk-utils.js +0 -24
  528. package/dist/server/utils/jwk-utils.js.map +0 -1
  529. package/dist/server/utils/jwt-utils.d.ts +0 -39
  530. package/dist/server/utils/jwt-utils.js +0 -87
  531. package/dist/server/utils/jwt-utils.js.map +0 -1
  532. package/src/server/hono/hubspot-connect-routes/auth-callback.test.ts +0 -225
@@ -1,4 +1,1459 @@
1
- import { secureStart } from "./deno/start.js";
2
- import { startHubSpotConnectFunction } from "./lovable/hubspot-connect/index.js";
3
- import { createAppFunctionStart } from "./lovable/create-app-function-start.js";
1
+ import { n as isBinaryData, r as createHubSpotClient } from "./binary-data-BOalJzKu.js";
2
+ import { c as base64url, i as signJwt, l as base64urlDecode, n as signDpopProof, o as getJwkThumbprint, s as base64StandardToArrayBuffer, t as sha256base64url } from "./sha256-B7y8GBFB.js";
3
+ import { Hono } from "hono";
4
+ //#region src/server/import-app-keys.ts
5
+ /**
6
+ * Imports a base64-encoded PKCS8 ES256 private key into the
7
+ * `AppKeys` shape used throughout the SDK.
8
+ *
9
+ * The function imports the key twice: once as **extractable** to
10
+ * derive the public JWK (via `crypto.subtle.exportKey`), and once
11
+ * as **non-extractable** so the long-lived `appPrivateKey` can never
12
+ * be exfiltrated.
13
+ *
14
+ * @throws {Error} When `envKey` is empty/undefined or when the key
15
+ * isn't an EC P-256 keypair.
16
+ */
17
+ async function importAppKeys(envKey) {
18
+ const b64 = envKey?.trim() ?? "";
19
+ if (!b64) throw new Error("HUBSPOT_APP_PRIVATE_KEY is not set");
20
+ const pkcs8 = base64StandardToArrayBuffer(b64);
21
+ const tempPrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, {
22
+ name: "ECDSA",
23
+ namedCurve: "P-256"
24
+ }, true, ["sign"]);
25
+ const privateJwk = await crypto.subtle.exportKey("jwk", tempPrivateKey);
26
+ if (privateJwk.kty !== "EC" || privateJwk.crv !== "P-256" || typeof privateJwk.x !== "string" || typeof privateJwk.y !== "string") throw new Error("Expected P-256 EC private key JWK with x and y");
27
+ const appPublicKeyJwk = {
28
+ kty: "EC",
29
+ crv: "P-256",
30
+ x: privateJwk.x,
31
+ y: privateJwk.y
32
+ };
33
+ return {
34
+ appPrivateKey: await crypto.subtle.importKey("pkcs8", pkcs8, {
35
+ name: "ECDSA",
36
+ namedCurve: "P-256"
37
+ }, false, ["sign"]),
38
+ appPublicKeyJwk
39
+ };
40
+ }
41
+ //#endregion
42
+ //#region src/server/utils/env-utils.ts
43
+ /**
44
+ * Reads an environment variable in a way that works under both Node
45
+ * (`process.env`) and Deno (`Deno.env.get`). Returns `undefined` when
46
+ * the variable is unset or when neither runtime is available.
47
+ */
48
+ function getEnv(key) {
49
+ const g = globalThis;
50
+ const proc = g.process;
51
+ if (proc?.env) return proc.env[key];
52
+ const deno = g.Deno;
53
+ if (deno !== void 0) return deno.env.get(key);
54
+ }
55
+ /**
56
+ * Reads an environment variable and throws when it is missing or empty.
57
+ * Use for values the SDK cannot fall back on (e.g. upstream service
58
+ * URLs).
59
+ *
60
+ * @throws {Error} When the environment variable is unset or an empty
61
+ * string.
62
+ */
63
+ function requireEnv(key) {
64
+ const value = getEnv(key);
65
+ if (!value) throw new Error(`Missing required environment variable: ${key}`);
66
+ return value;
67
+ }
68
+ /**
69
+ * Whether outbound HubSpot OAuth and API calls should attach DPoP on
70
+ * the wire. Disabled only when `HUBSPOT_DPOP_ENABLED` is exactly the
71
+ * string `"false"` (unset or any other value keeps DPoP enabled).
72
+ */
73
+ function isHubspotDpopEnabled() {
74
+ return getEnv("HUBSPOT_DPOP_ENABLED") !== "false";
75
+ }
76
+ /**
77
+ * Whether the SDK should use CIMD-style OAuth (client ID URL + JWT client
78
+ * assertion). Disabled only when `HUBSPOT_CIMD_ENABLED` is exactly the
79
+ * string `"false"` (unset or any other value keeps CIMD enabled).
80
+ */
81
+ function isHubspotCimdEnabled() {
82
+ return getEnv("HUBSPOT_CIMD_ENABLED") !== "false";
83
+ }
84
+ /**
85
+ * Whether `HUBSPOT_APP_PRIVATE_KEY` must be set for `secureStart`. False
86
+ * when both CIMD and DPoP are disabled — the SDK then uses
87
+ * `client_secret` for OAuth and Bearer tokens only for API calls.
88
+ */
89
+ function isHubspotAppPrivateKeyRequired() {
90
+ return isHubspotCimdEnabled() || isHubspotDpopEnabled();
91
+ }
92
+ //#endregion
93
+ //#region src/server/secure-start-core.ts
94
+ const APP_PRIVATE_KEY_ENV = "HUBSPOT_APP_PRIVATE_KEY";
95
+ /**
96
+ * Loads `HUBSPOT_APP_PRIVATE_KEY` when CIMD or DPoP is enabled, deletes
97
+ * it from the environment so later code cannot re-read it, imports the
98
+ * entrypoint module via `loader`, and invokes `start` with `AppKeys` or
99
+ * `null` when both features are off. On failure, logs the error and
100
+ * exits with code 1.
101
+ */
102
+ async function runSecureStart(loader, adapter) {
103
+ let appKeys = null;
104
+ if (isHubspotAppPrivateKeyRequired()) {
105
+ const envKey = adapter.readEnv(APP_PRIVATE_KEY_ENV)?.trim();
106
+ if (!envKey) throw new Error(`${APP_PRIVATE_KEY_ENV} is not set`);
107
+ appKeys = await importAppKeys(envKey);
108
+ adapter.deleteEnv(APP_PRIVATE_KEY_ENV);
109
+ }
110
+ return (await loader()).start({ appKeys }).catch((error) => {
111
+ console.error(error);
112
+ return adapter.exit(1);
113
+ });
114
+ }
115
+ //#endregion
116
+ //#region src/server/deno/start.ts
117
+ const denoSecureStartAdapter = {
118
+ readEnv: (key) => Deno.env.get(key),
119
+ deleteEnv: (key) => {
120
+ Deno.env.delete(key);
121
+ },
122
+ exit: (code) => Deno.exit(code)
123
+ };
124
+ /**
125
+ * Deno entrypoint helper. Reads `HUBSPOT_APP_PRIVATE_KEY` from `Deno.env`
126
+ * when CIMD or DPoP is enabled, imports the supplied loader, and invokes
127
+ * `start` with `AppKeys` or `null`.
128
+ */
129
+ function secureStart(loader) {
130
+ return runSecureStart(loader, denoSecureStartAdapter);
131
+ }
132
+ //#endregion
133
+ //#region src/server/hono/hubspot-connect-routes/cimd-client-metadata-types.ts
134
+ function assertHubSpotConnectCimdClientMetadata(value) {
135
+ const required = value.scope?.required;
136
+ if (!(Array.isArray(required) && required.length > 0 && required.every((s) => typeof s === "string" && s.length > 0))) throw new Error("HubSpotConnectCimdClientMetadata.scope.required must be a non-empty array of non-empty strings");
137
+ const optional = value.scope.optional;
138
+ if (optional === void 0) return;
139
+ if (!Array.isArray(optional)) throw new Error("HubSpotConnectCimdClientMetadata.scope.optional must be an array when set");
140
+ if (optional.length > 0 && !optional.every((s) => typeof s === "string" && s.length > 0)) throw new Error("HubSpotConnectCimdClientMetadata.scope.optional entries must be non-empty strings");
141
+ }
142
+ //#endregion
143
+ //#region src/shared/logger.ts
144
+ /**
145
+ * Logger that swallows every message. Convenient for tests and for
146
+ * the SDK's server-side handlers when no logger is provided by the
147
+ * host application.
148
+ */
149
+ const noopLogger = {
150
+ debug: () => {},
151
+ info: () => {},
152
+ warn: () => {},
153
+ error: () => {}
154
+ };
155
+ //#endregion
156
+ //#region src/server/api-client-core/plugins/fetch-transport.ts
157
+ const BASE_URL = "https://api.hubapi.com";
158
+ function appendRecordToUrlSearchParams(params, record) {
159
+ for (const [key, value] of Object.entries(record)) {
160
+ if (value == null) continue;
161
+ if (Array.isArray(value)) for (const item of value) params.append(key, String(item));
162
+ else params.append(key, String(value));
163
+ }
164
+ }
165
+ /**
166
+ * Transport plugin that executes HTTP requests using the Fetch API.
167
+ *
168
+ * This is the terminal middleware in the chain — it builds the actual HTTP
169
+ * request from the operation descriptor and returns a normalized response.
170
+ * It handles path-parameter interpolation, query-string serialization,
171
+ * Bearer-token auth, and content-type negotiation (JSON, form-urlencoded, multipart).
172
+ */
173
+ function fetchTransportPlugin(options) {
174
+ return { activate(api) {
175
+ api.addMiddleware(async (ctx) => {
176
+ const { operation } = ctx;
177
+ let url = `${BASE_URL}${operation.path}`;
178
+ if (operation.pathParams) for (const [key, value] of Object.entries(operation.pathParams)) url = url.replace(`{${key}}`, encodeURIComponent(String(value)));
179
+ if (operation.queryParams) {
180
+ const params = new URLSearchParams();
181
+ appendRecordToUrlSearchParams(params, operation.queryParams);
182
+ const qs = params.toString();
183
+ if (qs) url += `?${qs}`;
184
+ }
185
+ const headers = {
186
+ ...operation.headers ?? {},
187
+ Authorization: `Bearer ${options.getAccessToken()}`
188
+ };
189
+ const init = {
190
+ method: operation.method.toUpperCase(),
191
+ headers
192
+ };
193
+ if (operation.contentType === "multipart/form-data" && operation.body) {
194
+ const formData = new FormData();
195
+ for (const [key, value] of Object.entries(operation.body)) {
196
+ if (value == null) continue;
197
+ if (isBinaryData(value)) formData.append(key, value.source);
198
+ else formData.append(key, String(value));
199
+ }
200
+ init.body = formData;
201
+ } else if (operation.contentType === "application/x-www-form-urlencoded") {
202
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
203
+ if (operation.body) {
204
+ const params = new URLSearchParams();
205
+ appendRecordToUrlSearchParams(params, operation.body);
206
+ const encoded = params.toString();
207
+ if (encoded) init.body = encoded;
208
+ }
209
+ } else {
210
+ headers["Content-Type"] = "application/json";
211
+ if (operation.body) init.body = JSON.stringify(operation.body);
212
+ }
213
+ const response = await fetch(url, init);
214
+ const responseHeaders = Object.create(null);
215
+ response.headers.forEach((value, key) => {
216
+ responseHeaders[key] = value;
217
+ });
218
+ return {
219
+ status: response.status,
220
+ statusText: response.statusText,
221
+ headers: responseHeaders,
222
+ bodyJson: response.status === 204 ? void 0 : await response.json()
223
+ };
224
+ });
225
+ } };
226
+ }
227
+ //#endregion
228
+ //#region src/server/constants.ts
229
+ /**
230
+ * Cookie name carrying the DPoP-bound access token. Uses the
231
+ * `__Host-` prefix so the browser only accepts it from a `Secure`
232
+ * response with `Path=/` — a defense-in-depth against subdomain
233
+ * cookie injection.
234
+ */
235
+ const HUBSPOT_ACCESS_TOKEN_COOKIE_NAME = "__Host-hs_access_token";
236
+ /**
237
+ * Cookie carrying the opaque app-session ID. Hashed before being put
238
+ * on the wire as a DPoP `sid` claim.
239
+ */
240
+ const HUBSPOT_APP_SID_COOKIE_NAME = "__Host-hs_app_sid";
241
+ /**
242
+ * Cookie pinning the browser-facing app origin (e.g.
243
+ * `https://app.example.com`) for the lifetime of an app session.
244
+ * Set by `auth/init-session` from the request's `Origin` header and
245
+ * read by:
246
+ *
247
+ * - The CORS middleware to emit a credentialed
248
+ * `Access-Control-Allow-Origin` value (`*` is forbidden when
249
+ * `Access-Control-Allow-Credentials: true`).
250
+ * - `auth/complete` to rebuild the OAuth `redirect_uri` it sent to
251
+ * HubSpot during `init-session` (the token endpoint validates that
252
+ * the two values match).
253
+ *
254
+ * `__Host-` prefixed (Path=/, Secure, no Domain), so the same
255
+ * function host can serve both `hubspot-connect` and `api` routes
256
+ * and read the cookie from either.
257
+ */
258
+ const HUBSPOT_APP_ORIGIN_COOKIE_NAME = "__Host-hs_app_origin";
259
+ /**
260
+ * Prefix used for refresh-token cookies. Each session gets its own
261
+ * cookie name (`hs_refresh_<sidHash>`) so multiple devices/tabs can
262
+ * coexist without overwriting each other's refresh tokens.
263
+ */
264
+ const HUBSPOT_REFRESH_COOKIE_PREFIX = "hs_refresh_";
265
+ const PROTECTED_COOKIE_NAMES = new Set([
266
+ HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,
267
+ HUBSPOT_APP_SID_COOKIE_NAME,
268
+ HUBSPOT_APP_ORIGIN_COOKIE_NAME
269
+ ]);
270
+ /**
271
+ * Returns `true` for cookies the SDK manages internally
272
+ * (access token, session ID, any refresh-token cookie). The
273
+ * `sanitizeRequest` helper uses this to strip these cookies from the
274
+ * request before user code sees it, ensuring user route handlers
275
+ * cannot accidentally leak them in logs or proxy them upstream.
276
+ */
277
+ function isProtectedCookieName(cookieName) {
278
+ return PROTECTED_COOKIE_NAMES.has(cookieName) || cookieName.startsWith("hs_refresh_");
279
+ }
280
+ /**
281
+ * Cookie carrying the PKCE code verifier between `init-session` and
282
+ * `auth/complete`. Set with `SameSite=None; Secure; Partitioned` so the
283
+ * frontend's credentialed cross-site `POST /auth/complete` (made from
284
+ * the OAuth callback page on the app origin to the SDK's edge function
285
+ * origin) carries it through. `Lax` would silently drop it on that
286
+ * fetch, breaking every successful HubSpot redirect.
287
+ */
288
+ const TEMP_COOKIE_PKCE_VERIFIER = "__hs_pkce_verifier";
289
+ /**
290
+ * Cookie carrying the OAuth `state` value between `init-session` and
291
+ * `auth/complete`. Compared against the `state` query parameter as the
292
+ * primary CSRF defense. Same `SameSite=None; Secure; Partitioned`
293
+ * attributes as `TEMP_COOKIE_PKCE_VERIFIER` for the same cross-site
294
+ * `POST /auth/complete` reason.
295
+ */
296
+ const TEMP_COOKIE_OAUTH_STATE = "__hs_oauth_state";
297
+ //#endregion
298
+ //#region src/server/proxy.ts
299
+ const HUBSPOT_API_ORIGIN = requireEnv("HUBSPOT_API_ORIGIN");
300
+ const notAuthenticated = {
301
+ authenticated: false,
302
+ fetch: async () => {
303
+ return new Response(null, {
304
+ status: 401,
305
+ statusText: "Unauthorized",
306
+ headers: { "Content-Type": "application/json" }
307
+ });
308
+ }
309
+ };
310
+ const EMPTY_HEADERS = {};
311
+ function createHubSpotProxy(options) {
312
+ const { userCredentials, appKeys, logger = noopLogger } = options;
313
+ if (isHubspotDpopEnabled() && appKeys === null) throw new Error("createHubSpotProxy: appKeys is required when HUBSPOT_DPOP_ENABLED is not false");
314
+ const { accessToken, sessionId } = userCredentials;
315
+ if (!accessToken || !sessionId) {
316
+ logger.debug("createHubSpotProxy: returning unauthenticated proxy (missing cookies)");
317
+ return notAuthenticated;
318
+ }
319
+ async function proxyFetch(request) {
320
+ const { path, method = "GET", headers = EMPTY_HEADERS, body } = request;
321
+ const targetUrl = `${HUBSPOT_API_ORIGIN}${path}`;
322
+ const useDpop = isHubspotDpopEnabled();
323
+ let authorizationHeaders;
324
+ if (useDpop) {
325
+ const ath = await sha256base64url(accessToken);
326
+ const sid = await sha256base64url(sessionId);
327
+ const dpopProof = await signDpopProof({
328
+ appKeys,
329
+ claims: {
330
+ htm: method,
331
+ htu: targetUrl,
332
+ jti: crypto.randomUUID(),
333
+ iat: Math.floor(Date.now() / 1e3),
334
+ ath,
335
+ sid
336
+ }
337
+ });
338
+ authorizationHeaders = {
339
+ Authorization: `DPoP ${accessToken}`,
340
+ DPoP: dpopProof
341
+ };
342
+ } else authorizationHeaders = { Authorization: `Bearer ${accessToken}` };
343
+ const requestInit = {
344
+ headers: {
345
+ ...headers,
346
+ ...authorizationHeaders
347
+ },
348
+ method
349
+ };
350
+ if (body != null) requestInit.body = body;
351
+ return fetch(targetUrl, requestInit);
352
+ }
353
+ return {
354
+ authenticated: true,
355
+ fetch: proxyFetch
356
+ };
357
+ }
358
+ //#endregion
359
+ //#region src/server/utils/cookie-utils.ts
360
+ /**
361
+ * Parses an HTTP `Cookie` request header into a `name -> value` map.
362
+ * Tolerates leading/trailing whitespace, missing `=` (treats the
363
+ * cookie value as empty), and duplicate names (last write wins).
364
+ *
365
+ * Returns an empty object when `cookieHeader` is `null`/`undefined`
366
+ * /empty so callers don't have to null-check the input.
367
+ */
368
+ function parseCookies(cookieHeader) {
369
+ if (!cookieHeader) return {};
370
+ return Object.fromEntries(cookieHeader.split(";").map((pair) => {
371
+ const eqIdx = pair.indexOf("=");
372
+ if (eqIdx === -1) return [pair.trim(), ""];
373
+ return [pair.slice(0, eqIdx).trim(), pair.slice(eqIdx + 1).trim()];
374
+ }).filter(([name]) => name.length > 0));
375
+ }
376
+ //#endregion
377
+ //#region src/server/sanitize-request.ts
378
+ function serializeCookies(cookies) {
379
+ const parts = [];
380
+ for (const [name, value] of cookies) parts.push(`${name}=${value}`);
381
+ return parts.join("; ");
382
+ }
383
+ /**
384
+ * Mutates `headers` in place: parses the `Cookie` header, drops every
385
+ * protected cookie (see {@link isProtectedCookieName}), and rewrites
386
+ * the header. Deletes the header entirely when nothing survives.
387
+ *
388
+ * Used by the SDK's auth middleware after it has read the access
389
+ * token / session ID, so user route handlers never see — and
390
+ * therefore cannot leak — those cookies, while CORS / auth
391
+ * middleware that ran first still got the raw values.
392
+ */
393
+ function stripProtectedCookies(headers) {
394
+ const cookies = parseCookies(headers.get("Cookie"));
395
+ const surviving = /* @__PURE__ */ new Map();
396
+ for (const [name, value] of Object.entries(cookies)) if (!isProtectedCookieName(name)) surviving.set(name, value);
397
+ if (surviving.size === 0) headers.delete("cookie");
398
+ else headers.set("cookie", serializeCookies(surviving));
399
+ }
400
+ /**
401
+ * Returns a clone of `original` whose `Cookie` header has every
402
+ * protected cookie removed (see {@link isProtectedCookieName}). When
403
+ * no other cookies remain, the header is dropped entirely.
404
+ *
405
+ * Standalone helper retained for callers that want a new Request
406
+ * (e.g. tests). Inside the SDK's per-request handler, the auth
407
+ * middleware uses {@link stripProtectedCookies} directly on
408
+ * `c.req.raw.headers` so the auth check itself can still read the
409
+ * protected cookies before they are stripped.
410
+ */
411
+ function sanitizeRequest(original) {
412
+ const headers = new Headers(original.headers);
413
+ stripProtectedCookies(headers);
414
+ const init = {
415
+ method: original.method,
416
+ headers,
417
+ redirect: original.redirect,
418
+ signal: original.signal
419
+ };
420
+ if (original.body !== null) {
421
+ init.body = original.body;
422
+ init.duplex = "half";
423
+ }
424
+ return new Request(original.url, init);
425
+ }
426
+ //#endregion
427
+ //#region src/server/hono/utils/cors-middleware.ts
428
+ /**
429
+ * Comma-separated list of request headers the SDK accepts on
430
+ * cross-site fetches. Mirrors the Supabase Edge Functions defaults
431
+ * the Lovable AI agent emits today, plus `content-type` for the
432
+ * `auth/complete` POST body and `accept` so JSON content negotiation
433
+ * works.
434
+ */
435
+ const ALLOWED_HEADERS = [
436
+ "authorization",
437
+ "x-client-info",
438
+ "apikey",
439
+ "content-type",
440
+ "accept",
441
+ "x-supabase-client-platform",
442
+ "x-supabase-client-platform-version",
443
+ "x-supabase-client-runtime",
444
+ "x-supabase-client-runtime-version"
445
+ ].join(", ");
446
+ const ALLOWED_METHODS = "GET, POST, OPTIONS";
447
+ const PREFLIGHT_MAX_AGE_SECONDS = "600";
448
+ /**
449
+ * Reads the persisted app-origin cookie from the request, falling
450
+ * back to the literal `Origin` request header. The cookie is the
451
+ * authoritative pin once `auth/init-session` has run; on the very
452
+ * first init-session call (no cookie yet) we just echo whatever
453
+ * `Origin` the caller sent — the actual access decision is enforced
454
+ * by cookie-based authentication on every other route, not by CORS.
455
+ */
456
+ function resolveAllowedOrigin(c) {
457
+ const pinned = parseCookies(c.req.header("Cookie"))[HUBSPOT_APP_ORIGIN_COOKIE_NAME];
458
+ if (pinned) return pinned;
459
+ return c.req.header("Origin") ?? null;
460
+ }
461
+ function setSharedCorsHeaders(c, allowOrigin) {
462
+ c.res.headers.set("Access-Control-Allow-Origin", allowOrigin);
463
+ c.res.headers.set("Access-Control-Allow-Credentials", "true");
464
+ c.res.headers.set("Vary", "Origin, Cookie");
465
+ }
466
+ /**
467
+ * Hono middleware that emits credentialed CORS response headers for
468
+ * the cross-origin Lovable / Supabase deployment shape.
469
+ *
470
+ * - On `OPTIONS` preflight: short-circuits with a 204 carrying
471
+ * `Access-Control-Allow-*` headers. The browser will then send the
472
+ * real request with cookies attached.
473
+ * - On every other method: echoes the pinned `__Host-hs_app_origin`
474
+ * cookie value (or, before init-session has run, the request
475
+ * `Origin` header) as `Access-Control-Allow-Origin`, with
476
+ * `Access-Control-Allow-Credentials: true`. The wildcard `*` is
477
+ * forbidden by browsers when credentials are included, so the
478
+ * middleware always echoes a concrete origin.
479
+ *
480
+ * Skips header emission entirely when the request has no `Origin`
481
+ * (server-to-server calls, curl, etc.) so non-browser callers are
482
+ * left untouched.
483
+ */
484
+ function corsMiddleware() {
485
+ return async (c, next) => {
486
+ const allowOrigin = resolveAllowedOrigin(c);
487
+ if (c.req.method === "OPTIONS") {
488
+ const headers = new Headers();
489
+ if (allowOrigin) {
490
+ headers.set("Access-Control-Allow-Origin", allowOrigin);
491
+ headers.set("Access-Control-Allow-Credentials", "true");
492
+ headers.set("Vary", "Origin, Cookie");
493
+ }
494
+ headers.set("Access-Control-Allow-Methods", ALLOWED_METHODS);
495
+ headers.set("Access-Control-Allow-Headers", ALLOWED_HEADERS);
496
+ headers.set("Access-Control-Max-Age", PREFLIGHT_MAX_AGE_SECONDS);
497
+ return new Response(null, {
498
+ status: 204,
499
+ headers
500
+ });
501
+ }
502
+ await next();
503
+ if (allowOrigin) setSharedCorsHeaders(c, allowOrigin);
504
+ };
505
+ }
506
+ //#endregion
507
+ //#region src/server/hono/hono-request-handler.ts
508
+ /**
509
+ * Wraps a Hono app so its `fetch` handler additionally:
510
+ *
511
+ * - Strips SDK-managed cookies (access token, refresh, sid) from the
512
+ * request before the app sees them, via `sanitizeRequest`.
513
+ * - Exposes a `hubSpotProxy` on the Hono context so route handlers
514
+ * can issue authenticated calls to HubSpot's API on behalf of the
515
+ * browser session.
516
+ */
517
+ function createAppConnectRequestHandler(options) {
518
+ const { registerRoutes, appKeys, logger = noopLogger } = options;
519
+ const app = new Hono();
520
+ app.use("*", corsMiddleware());
521
+ app.use("*", async (c, next) => {
522
+ const { authenticated } = c.env.hubSpot;
523
+ if (!authenticated) return c.json({ error: "Unauthorized" }, 401);
524
+ await next();
525
+ });
526
+ registerRoutes(app);
527
+ return (request) => {
528
+ const cookie = request.headers.get("Cookie");
529
+ if (!cookie) throw new Error("Missing auth cookies");
530
+ const cookies = parseCookies(cookie);
531
+ const accessToken = cookies[HUBSPOT_ACCESS_TOKEN_COOKIE_NAME];
532
+ const proxy = createHubSpotProxy({
533
+ userCredentials: {
534
+ accessToken,
535
+ sessionId: cookies[HUBSPOT_APP_SID_COOKIE_NAME]
536
+ },
537
+ appKeys,
538
+ logger
539
+ });
540
+ const client = createHubSpotClient({ plugins: [fetchTransportPlugin({ getAccessToken: () => {
541
+ if (!accessToken) throw new Error("Missing access token");
542
+ return accessToken;
543
+ } })] });
544
+ const sanitizedRequest = sanitizeRequest(request);
545
+ const honoBindings = { hubSpot: {
546
+ proxy,
547
+ client,
548
+ authenticated: proxy.authenticated
549
+ } };
550
+ return app.fetch(sanitizedRequest, honoBindings);
551
+ };
552
+ }
553
+ //#endregion
554
+ //#region src/shared/constants.ts
555
+ /**
556
+ * Path the browser visits after HubSpot's authorize endpoint
557
+ * redirects back to the app. Mounted on the **frontend** origin (not
558
+ * the SDK's edge function host) so all OAuth-related cookies live in
559
+ * the `(frontend, edge)` CHIPS partition.
560
+ *
561
+ * The SDK's `auth/init-session` builds the OAuth `redirect_uri` as
562
+ * `${requestOrigin}${HUBSPOT_FRONTEND_CALLBACK_PATH}`. The browser
563
+ * controller, on `start()`, recognizes this path on `window.location`
564
+ * and forwards `?code` + `?state` to the SDK's `auth/complete`
565
+ * endpoint via a credentialed cross-site fetch. The host app must
566
+ * register `${app_origin}${HUBSPOT_FRONTEND_CALLBACK_PATH}` as a
567
+ * redirect URI in its HubSpot app settings.
568
+ */
569
+ const HUBSPOT_FRONTEND_CALLBACK_PATH = "/__hubspot_oauth_callback";
570
+ /**
571
+ * Query parameter on the `auth/complete` POST request carrying the
572
+ * authorization `code` HubSpot returned to the frontend callback.
573
+ */
574
+ const AUTH_COMPLETE_CODE_PARAM = "code";
575
+ /**
576
+ * Query parameter on the `auth/complete` POST request carrying the
577
+ * OAuth `state` HubSpot echoed back to the frontend callback.
578
+ */
579
+ const AUTH_COMPLETE_STATE_PARAM = "state";
580
+ //#endregion
581
+ //#region src/server/hono/utils/cookie-utils.ts
582
+ /**
583
+ * Appends a `Set-Cookie` header to the response. Hono replaces single
584
+ * headers by default, so this uses `{ append: true }` to emit multiple
585
+ * cookies on the same response.
586
+ */
587
+ function setResponseCookie(options) {
588
+ const { c, value } = options;
589
+ c.header("Set-Cookie", value, { append: true });
590
+ }
591
+ /**
592
+ * Builds a `Set-Cookie` header value with HubSpot's default attributes
593
+ * (HttpOnly, Secure, SameSite). Centralizes the serialization so all
594
+ * cookies share the same policy.
595
+ */
596
+ function serializeCookie(options) {
597
+ const { name, value, path, sameSite = "Strict", maxAge, secure = true, httpOnly = true, partitioned = false } = options;
598
+ const parts = [`${name}=${value}`];
599
+ if (httpOnly) parts.push("HttpOnly");
600
+ if (secure) parts.push("Secure");
601
+ parts.push(`SameSite=${sameSite}`);
602
+ parts.push(`Path=${path}`);
603
+ parts.push(`Max-Age=${maxAge}`);
604
+ if (partitioned) parts.push("Partitioned");
605
+ return parts.join("; ");
606
+ }
607
+ //#endregion
608
+ //#region src/server/hono/hubspot-connect-routes/constants.ts
609
+ const SESSION_MAX_AGE_SEC = 2592e3;
610
+ const OAUTH_TEMP_MAX_AGE_SEC = 3600;
611
+ const REFRESH_COOKIE_MAX_AGE_SEC = 2592e3;
612
+ //#endregion
613
+ //#region src/server/hono/hubspot-connect-routes/oauth-client.ts
614
+ /**
615
+ * Lifetime of the OAuth `client_assertion` JWT in seconds. Short by
616
+ * design — RFC 7521 recommends short-lived assertions, and HubSpot's
617
+ * authorization server rejects assertions older than ~5 minutes.
618
+ */
619
+ const CLIENT_ASSERTION_TTL_SEC = 60;
620
+ /**
621
+ * The `client_assertion_type` value mandated by RFC 7523 §2.2 for
622
+ * JWT-bearer client authentication.
623
+ */
624
+ const JWT_BEARER_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
625
+ /**
626
+ * Mints a short-lived ES256 JWT used as the `client_assertion`
627
+ * parameter when calling HubSpot's token endpoint, per RFC 7523.
628
+ */
629
+ async function buildClientAssertion(options) {
630
+ const { appKeys, clientId, audience } = options;
631
+ return signJwt({
632
+ privateKey: appKeys.appPrivateKey,
633
+ payload: {
634
+ iss: clientId,
635
+ sub: clientId,
636
+ aud: audience,
637
+ jti: crypto.randomUUID()
638
+ },
639
+ ttlSeconds: CLIENT_ASSERTION_TTL_SEC
640
+ });
641
+ }
642
+ /**
643
+ * Signs a DPoP proof for a `POST` to HubSpot's token endpoint. RFC 9449
644
+ * binds the resulting access token to the proving public key so that
645
+ * later API calls must come from the same key holder.
646
+ */
647
+ async function buildTokenEndpointDpopProof(options) {
648
+ const { appKeys, tokenEndpointUrl, sessionIdHash } = options;
649
+ return signDpopProof({
650
+ appKeys,
651
+ claims: {
652
+ htm: "POST",
653
+ htu: tokenEndpointUrl,
654
+ jti: crypto.randomUUID(),
655
+ iat: Math.floor(Date.now() / 1e3),
656
+ sid: sessionIdHash
657
+ }
658
+ });
659
+ }
660
+ /**
661
+ * POSTs an `application/x-www-form-urlencoded` body to a HubSpot token
662
+ * endpoint. Attaches a `DPoP` header when `isDpopEnabled` is true and
663
+ * `dpopProof` is provided. Reads the response once — either
664
+ * as JSON on success or as text on failure — so callers never have to
665
+ * consume the body twice.
666
+ */
667
+ async function requestOAuthToken(options) {
668
+ const { tokenEndpointUrl, formParams, dpopProof, isDpopEnabled } = options;
669
+ const headers = { "Content-Type": "application/x-www-form-urlencoded" };
670
+ if (isDpopEnabled) {
671
+ if (!dpopProof) throw new Error("DPoP proof is required when DPoP is enabled");
672
+ headers.DPoP = dpopProof;
673
+ }
674
+ const tokenResponse = await fetch(tokenEndpointUrl, {
675
+ method: "POST",
676
+ headers,
677
+ body: new URLSearchParams(formParams)
678
+ });
679
+ if (!tokenResponse.ok) {
680
+ const errorText = await tokenResponse.text();
681
+ return {
682
+ ok: false,
683
+ status: tokenResponse.status,
684
+ errorText
685
+ };
686
+ }
687
+ return {
688
+ ok: true,
689
+ body: await tokenResponse.json()
690
+ };
691
+ }
692
+ /**
693
+ * Form parameters always present on the OAuth `client_assertion` flow.
694
+ * Spread into the call site's `formParams`.
695
+ */
696
+ function buildClientAssertionFormParams(input) {
697
+ const { clientId, clientAssertion } = input;
698
+ return {
699
+ client_id: clientId,
700
+ client_assertion_type: JWT_BEARER_ASSERTION_TYPE,
701
+ client_assertion: clientAssertion
702
+ };
703
+ }
704
+ function buildClientSecretFormParams(options) {
705
+ const { clientId, clientSecret } = options;
706
+ return {
707
+ client_id: clientId,
708
+ client_secret: clientSecret
709
+ };
710
+ }
711
+ //#endregion
712
+ //#region src/server/hono/hubspot-connect-routes/utils.ts
713
+ function clearTempCookie(name) {
714
+ return serializeCookie({
715
+ name,
716
+ value: "",
717
+ path: "/",
718
+ sameSite: "None",
719
+ maxAge: 0,
720
+ partitioned: true
721
+ });
722
+ }
723
+ /**
724
+ * Parses the request `Origin` header into the canonical origin
725
+ * string (`URL.origin`) or returns `null` when the header is
726
+ * missing, malformed, or carries a scheme/host the SDK does not
727
+ * accept.
728
+ *
729
+ * Accepted shapes:
730
+ *
731
+ * - `https://<host>` for production deployments.
732
+ * - `http://localhost[:<port>]` and `http://127.0.0.1[:<port>]`
733
+ * for local development; browsers exempt these from the `Secure`
734
+ * cookie restriction.
735
+ *
736
+ * Rejects values with a path/query/hash component (the request
737
+ * `Origin` header is by spec a bare origin, so anything else
738
+ * indicates a malformed or hostile request).
739
+ */
740
+ function parseAppOriginHeader(originHeader) {
741
+ if (!originHeader) return null;
742
+ let parsed;
743
+ try {
744
+ parsed = new URL(originHeader);
745
+ } catch {
746
+ return null;
747
+ }
748
+ if (parsed.pathname !== "/" && parsed.pathname !== "") return null;
749
+ if (parsed.search !== "" || parsed.hash !== "") return null;
750
+ if (parsed.protocol === "https:") return parsed.origin;
751
+ if (parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1")) return parsed.origin;
752
+ return null;
753
+ }
754
+ /**
755
+ * OAuth `redirect_uri` for the cross-origin app shape: the OAuth
756
+ * callback lands on the **frontend** origin (not the SDK's edge
757
+ * function host), so all cookies set by `init-session` and read by
758
+ * `auth/complete` live in the same `(frontend, edge)` CHIPS
759
+ * partition.
760
+ *
761
+ * Used by `auth/init-session` (when building `authorization_url`)
762
+ * and `auth/complete` (which must rebuild the same value to satisfy
763
+ * the OAuth token endpoint's `redirect_uri` check).
764
+ */
765
+ function buildFrontendOAuthRedirectUri(appOrigin) {
766
+ return `${appOrigin}${HUBSPOT_FRONTEND_CALLBACK_PATH}`;
767
+ }
768
+ function isSafeReturnPath(rawPath) {
769
+ if (!rawPath.startsWith("/")) return false;
770
+ if (rawPath.includes("\0")) return false;
771
+ let decoded;
772
+ try {
773
+ decoded = decodeURIComponent(rawPath);
774
+ } catch {
775
+ return false;
776
+ }
777
+ if (!decoded.startsWith("/")) return false;
778
+ const second = decoded.charAt(1);
779
+ if (second === "/" || second === "\\") return false;
780
+ return true;
781
+ }
782
+ function normalizeHubSpotConnectBasePath(basePath) {
783
+ return basePath.endsWith("/") && basePath.length > 1 ? basePath.slice(0, -1) : basePath;
784
+ }
785
+ /**
786
+ * Public origin for hubspot-connect URLs (`redirect_uri`, CIMD `client_id`,
787
+ * `jwks_uri`). Matches the host/proto rules used for the OAuth callback.
788
+ */
789
+ function buildHubSpotConnectRequestOrigin(options) {
790
+ const { requestUrl, xForwardedProto, xForwardedHost, requestHostHeader } = options;
791
+ const proto = xForwardedProto?.split(",")[0]?.trim();
792
+ if (proto && (proto === "http" || proto === "https")) {
793
+ const forwardedHost = xForwardedHost?.split(",")[0]?.trim();
794
+ const hostHeader = requestHostHeader?.split(",")[0]?.trim();
795
+ return `${proto}://${forwardedHost || hostHeader || new URL(requestUrl).host}`;
796
+ }
797
+ return new URL(requestUrl).origin;
798
+ }
799
+ /**
800
+ * OAuth `redirect_uri` for the hubspot-connect callback. Uses
801
+ * `X-Forwarded-Proto` with `X-Forwarded-Host`, then `Host`, then the request URL
802
+ * host when the proto is forwarded (reverse proxy); otherwise the request URL
803
+ * origin.
804
+ */
805
+ function buildOAuthRedirectUriFromRequest(options) {
806
+ const trimmed = normalizeHubSpotConnectBasePath(options.basePath);
807
+ return `${buildHubSpotConnectRequestOrigin(options)}${trimmed}/auth/callback`;
808
+ }
809
+ /**
810
+ * CIMD `client_id` URL: `{origin}{basePath}/client.json`.
811
+ */
812
+ function buildCimdClientIdUrlFromRequest(options) {
813
+ const trimmed = normalizeHubSpotConnectBasePath(options.basePath);
814
+ return `${buildHubSpotConnectRequestOrigin(options)}${trimmed}/client.json`;
815
+ }
816
+ /**
817
+ * App JWKS URL published in CIMD: `{origin}{basePath}/jwks.json`.
818
+ */
819
+ function buildHubSpotAppJwksUrlFromRequest(options) {
820
+ const trimmed = normalizeHubSpotConnectBasePath(options.basePath);
821
+ return `${buildHubSpotConnectRequestOrigin(options)}${trimmed}/jwks.json`;
822
+ }
823
+ function isPositiveFiniteNumber(value) {
824
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
825
+ }
826
+ //#endregion
827
+ //#region src/server/hono/hubspot-connect-routes/auth-complete.ts
828
+ /**
829
+ * Cross-origin OAuth completion endpoint.
830
+ *
831
+ * Called from the React app on the frontend OAuth callback path
832
+ * (`HUBSPOT_FRONTEND_CALLBACK_PATH`) once HubSpot has redirected the
833
+ * browser back with `?code` + `?state`. The browser POSTs both
834
+ * values here as a credentialed cross-site fetch — same partition as
835
+ * `init-session`, so the temp PKCE/state cookies are visible — and
836
+ * the SDK:
837
+ *
838
+ * 1. Validates `state` against the temp `__hs_oauth_state` cookie.
839
+ * 2. Pulls the PKCE verifier from `__hs_pkce_verifier`.
840
+ * 3. Rebuilds the same `redirect_uri` it sent to HubSpot during
841
+ * `init-session` (frontend origin + the fixed callback path);
842
+ * the OAuth token endpoint requires the two values to match.
843
+ * 4. Exchanges `code` for an access + refresh token (with DPoP /
844
+ * CIMD client-assertion when enabled).
845
+ * 5. Sets the durable session cookies (access token, refresh) with
846
+ * `SameSite=None; Secure; Partitioned` so they live in the
847
+ * `(frontend, edge)` partition where subsequent API fetches will
848
+ * read them.
849
+ * 6. Clears the temp cookies.
850
+ * 7. Returns `{ expires_at, return_path }` so the controller can
851
+ * update its session-storage expiry tracking and navigate back to
852
+ * the page the user started the connect flow from.
853
+ */
854
+ async function handleAuthComplete(c, options) {
855
+ const { appKeys, refreshCookiePath, hubspotConnectEnv } = options;
856
+ const xForwardedProto = c.req.header("x-forwarded-proto") ?? void 0;
857
+ const xForwardedHost = c.req.header("x-forwarded-host") ?? void 0;
858
+ const requestHostHeader = c.req.header("host") ?? void 0;
859
+ const code = c.req.query(AUTH_COMPLETE_CODE_PARAM);
860
+ const state = c.req.query(AUTH_COMPLETE_STATE_PARAM);
861
+ if (!code || !state) return c.json({ error: "Missing code or state" }, 400);
862
+ if (hubspotConnectEnv.isAppPrivateKeyRequired && !appKeys) return c.json({ error: "Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD or DPoP is enabled" }, 500);
863
+ const cookies = parseCookies(c.req.header("Cookie"));
864
+ const expectedState = cookies[TEMP_COOKIE_OAUTH_STATE];
865
+ const codeVerifier = cookies[TEMP_COOKIE_PKCE_VERIFIER];
866
+ const appOriginCookie = cookies[HUBSPOT_APP_ORIGIN_COOKIE_NAME];
867
+ if (!expectedState || state !== decodeURIComponent(expectedState)) return c.json({ error: "State mismatch" }, 403);
868
+ if (!codeVerifier) return c.json({ error: "Missing PKCE verifier" }, 400);
869
+ const appOrigin = parseAppOriginHeader(appOriginCookie);
870
+ if (!appOrigin) return c.json({ error: "Missing app origin cookie" }, 400);
871
+ let statePayload;
872
+ try {
873
+ statePayload = JSON.parse(new TextDecoder().decode(base64urlDecode(decodeURIComponent(state))));
874
+ } catch {
875
+ return c.json({ error: "Malformed state value" }, 400);
876
+ }
877
+ const returnPath = statePayload.return_path;
878
+ if (!returnPath || !isSafeReturnPath(returnPath)) return c.json({ error: "Invalid return path in state" }, 400);
879
+ const sessionId = statePayload.sid;
880
+ if (!sessionId) return c.json({ error: "Missing app session cookie" }, 400);
881
+ const decodedCodeVerifier = decodeURIComponent(codeVerifier);
882
+ const clientId = hubspotConnectEnv.isCimdEnabled ? buildCimdClientIdUrlFromRequest({
883
+ requestUrl: c.req.url,
884
+ basePath: options.basePath,
885
+ xForwardedProto,
886
+ xForwardedHost,
887
+ requestHostHeader
888
+ }) : hubspotConnectEnv.hubspotClientId;
889
+ const redirectUri = buildFrontendOAuthRedirectUri(appOrigin);
890
+ const tokenEndpointUrl = new URL("/oauth/v1/token", hubspotConnectEnv.hubspotOAuthApiOrigin).href;
891
+ let dpopProof;
892
+ if (hubspotConnectEnv.isDpopEnabled) dpopProof = await buildTokenEndpointDpopProof({
893
+ appKeys,
894
+ tokenEndpointUrl,
895
+ sessionIdHash: sessionId
896
+ });
897
+ let formParams;
898
+ if (hubspotConnectEnv.isCimdEnabled) formParams = {
899
+ grant_type: "authorization_code",
900
+ code,
901
+ code_verifier: decodedCodeVerifier,
902
+ redirect_uri: redirectUri,
903
+ ...buildClientAssertionFormParams({
904
+ clientId,
905
+ clientAssertion: await buildClientAssertion({
906
+ appKeys,
907
+ clientId,
908
+ audience: tokenEndpointUrl
909
+ })
910
+ })
911
+ };
912
+ else formParams = {
913
+ grant_type: "authorization_code",
914
+ code,
915
+ code_verifier: decodedCodeVerifier,
916
+ redirect_uri: redirectUri,
917
+ ...buildClientSecretFormParams({
918
+ clientId,
919
+ clientSecret: hubspotConnectEnv.hubspotClientSecret
920
+ })
921
+ };
922
+ const tokenResult = await requestOAuthToken({
923
+ tokenEndpointUrl,
924
+ isDpopEnabled: hubspotConnectEnv.isDpopEnabled,
925
+ ...dpopProof !== void 0 ? { dpopProof } : {},
926
+ formParams
927
+ });
928
+ if (!tokenResult.ok) return c.json({ error: `Token exchange failed: ${tokenResult.errorText}` }, 502);
929
+ const { access_token: accessToken, refresh_token: refreshToken, expires_in } = tokenResult.body;
930
+ if (!refreshToken) return c.json({ error: "Token response missing refresh_token" }, 502);
931
+ if (!isPositiveFiniteNumber(expires_in)) return c.json({ error: "Token response missing or invalid expires_in" }, 502);
932
+ const expiresAt = Date.now() + expires_in * 1e3;
933
+ const refreshCookieName = `${HUBSPOT_REFRESH_COOKIE_PREFIX}${sessionId}`;
934
+ setResponseCookie({
935
+ c,
936
+ value: serializeCookie({
937
+ name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,
938
+ value: accessToken,
939
+ path: "/",
940
+ sameSite: "None",
941
+ partitioned: true,
942
+ maxAge: expires_in
943
+ })
944
+ });
945
+ setResponseCookie({
946
+ c,
947
+ value: serializeCookie({
948
+ name: refreshCookieName,
949
+ value: refreshToken,
950
+ path: refreshCookiePath,
951
+ sameSite: "None",
952
+ partitioned: true,
953
+ maxAge: REFRESH_COOKIE_MAX_AGE_SEC
954
+ })
955
+ });
956
+ setResponseCookie({
957
+ c,
958
+ value: clearTempCookie(TEMP_COOKIE_PKCE_VERIFIER)
959
+ });
960
+ setResponseCookie({
961
+ c,
962
+ value: clearTempCookie(TEMP_COOKIE_OAUTH_STATE)
963
+ });
964
+ return c.json({
965
+ expires_at: expiresAt,
966
+ return_path: returnPath
967
+ });
968
+ }
969
+ //#endregion
970
+ //#region src/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.ts
971
+ /**
972
+ * Builds `scope` and `optional_scope` query values for HubSpot
973
+ * `/oauth/authorize` from in-memory client metadata (same shape as
974
+ * `HubSpotConnectCimdClientMetadata` / `startHubSpotConnectFunction({ client })`).
975
+ */
976
+ function deriveHubSpotAuthorizeScopesFromClientMetadata(metadata) {
977
+ const required = metadata.scope?.required;
978
+ if (!(Array.isArray(required) && required.length > 0 && required.every((s) => typeof s === "string" && s.length > 0))) return {
979
+ ok: false,
980
+ status: 500,
981
+ message: "Invalid or empty scope.required in client metadata"
982
+ };
983
+ const scope = required.join(" ");
984
+ const optionalRaw = metadata.scope.optional;
985
+ if (optionalRaw == null) return {
986
+ ok: true,
987
+ scope
988
+ };
989
+ if (!Array.isArray(optionalRaw)) return {
990
+ ok: false,
991
+ status: 500,
992
+ message: "Invalid scope.optional in client metadata"
993
+ };
994
+ if (optionalRaw.length === 0) return {
995
+ ok: true,
996
+ scope
997
+ };
998
+ if (!optionalRaw.every((s) => typeof s === "string" && s.length > 0)) return {
999
+ ok: false,
1000
+ status: 500,
1001
+ message: "Invalid scope.optional in client metadata"
1002
+ };
1003
+ return {
1004
+ ok: true,
1005
+ scope,
1006
+ optionalScope: optionalRaw.join(" ")
1007
+ };
1008
+ }
1009
+ //#endregion
1010
+ //#region src/server/hono/hubspot-connect-routes/auth-init-session.ts
1011
+ async function handleAuthInitSession(c, options) {
1012
+ const { hubspotConnectEnv, cimdClientMetadata } = options;
1013
+ const xForwardedProto = c.req.header("x-forwarded-proto") ?? void 0;
1014
+ const xForwardedHost = c.req.header("x-forwarded-host") ?? void 0;
1015
+ const requestHostHeader = c.req.header("host") ?? void 0;
1016
+ const returnPath = new URL(c.req.url).searchParams.get("return_path") ?? "/";
1017
+ if (!isSafeReturnPath(returnPath)) return c.text("Invalid return_path", 400);
1018
+ const appOrigin = parseAppOriginHeader(c.req.header("Origin"));
1019
+ if (!appOrigin) return c.text("Missing or invalid Origin header; init-session must be called from a browser", 400);
1020
+ const sessionIdBytes = new Uint8Array(32);
1021
+ crypto.getRandomValues(sessionIdBytes);
1022
+ const sessionId = base64url(sessionIdBytes);
1023
+ const sessionIdHash = await sha256base64url(sessionId);
1024
+ const codeVerifierBytes = new Uint8Array(32);
1025
+ crypto.getRandomValues(codeVerifierBytes);
1026
+ const codeVerifier = base64url(codeVerifierBytes);
1027
+ const codeChallenge = await sha256base64url(codeVerifier);
1028
+ const stateValue = base64url(new TextEncoder().encode(JSON.stringify({
1029
+ return_path: returnPath,
1030
+ sid: sessionIdHash
1031
+ })));
1032
+ const clientId = hubspotConnectEnv.isCimdEnabled ? buildCimdClientIdUrlFromRequest({
1033
+ requestUrl: c.req.url,
1034
+ basePath: options.basePath,
1035
+ xForwardedProto,
1036
+ xForwardedHost,
1037
+ requestHostHeader
1038
+ }) : hubspotConnectEnv.hubspotClientId;
1039
+ const redirectUri = buildFrontendOAuthRedirectUri(appOrigin);
1040
+ const authorizeUrl = new URL(hubspotConnectEnv.hubspotAuthorizationEndpoint);
1041
+ authorizeUrl.searchParams.set("response_type", "code");
1042
+ authorizeUrl.searchParams.set("client_id", clientId);
1043
+ authorizeUrl.searchParams.set("redirect_uri", redirectUri);
1044
+ authorizeUrl.searchParams.set("code_challenge", codeChallenge);
1045
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
1046
+ authorizeUrl.searchParams.set("state", stateValue);
1047
+ authorizeUrl.searchParams.set("sid", sessionIdHash);
1048
+ if (!hubspotConnectEnv.isCimdEnabled) {
1049
+ const scopesResult = deriveHubSpotAuthorizeScopesFromClientMetadata(cimdClientMetadata);
1050
+ if (!scopesResult.ok) return c.text(scopesResult.message, scopesResult.status);
1051
+ authorizeUrl.searchParams.set("scope", scopesResult.scope);
1052
+ if (scopesResult.optionalScope !== void 0) authorizeUrl.searchParams.set("optional_scope", scopesResult.optionalScope);
1053
+ }
1054
+ setResponseCookie({
1055
+ c,
1056
+ value: serializeCookie({
1057
+ name: HUBSPOT_APP_ORIGIN_COOKIE_NAME,
1058
+ value: appOrigin,
1059
+ path: "/",
1060
+ sameSite: "None",
1061
+ partitioned: true,
1062
+ maxAge: SESSION_MAX_AGE_SEC
1063
+ })
1064
+ });
1065
+ setResponseCookie({
1066
+ c,
1067
+ value: serializeCookie({
1068
+ name: HUBSPOT_APP_SID_COOKIE_NAME,
1069
+ value: sessionId,
1070
+ path: "/",
1071
+ sameSite: "None",
1072
+ partitioned: true,
1073
+ maxAge: SESSION_MAX_AGE_SEC
1074
+ })
1075
+ });
1076
+ setResponseCookie({
1077
+ c,
1078
+ value: serializeCookie({
1079
+ name: TEMP_COOKIE_PKCE_VERIFIER,
1080
+ value: encodeURIComponent(codeVerifier),
1081
+ path: "/",
1082
+ sameSite: "None",
1083
+ partitioned: true,
1084
+ maxAge: OAUTH_TEMP_MAX_AGE_SEC
1085
+ })
1086
+ });
1087
+ setResponseCookie({
1088
+ c,
1089
+ value: serializeCookie({
1090
+ name: TEMP_COOKIE_OAUTH_STATE,
1091
+ value: encodeURIComponent(stateValue),
1092
+ path: "/",
1093
+ sameSite: "None",
1094
+ partitioned: true,
1095
+ maxAge: OAUTH_TEMP_MAX_AGE_SEC
1096
+ })
1097
+ });
1098
+ return c.json({ authorization_url: authorizeUrl.toString() });
1099
+ }
1100
+ //#endregion
1101
+ //#region src/server/hono/hubspot-connect-routes/auth-logout.ts
1102
+ async function revokeToken(options) {
1103
+ const { revokeEndpointUrl, body, logger } = options;
1104
+ try {
1105
+ const response = await fetch(revokeEndpointUrl, {
1106
+ method: "POST",
1107
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1108
+ body
1109
+ });
1110
+ if (!response.ok) logger.warn(`HubSpot token revoke returned HTTP ${response.status} ${response.statusText}`);
1111
+ } catch (error) {
1112
+ logger.warn("HubSpot token revoke request failed", error);
1113
+ }
1114
+ }
1115
+ async function handleAuthLogout(c, options) {
1116
+ const { appKeys, refreshCookiePath, basePath, hubspotConnectEnv, logger } = options;
1117
+ const xForwardedProto = c.req.header("x-forwarded-proto") ?? void 0;
1118
+ const xForwardedHost = c.req.header("x-forwarded-host") ?? void 0;
1119
+ const requestHostHeader = c.req.header("host") ?? void 0;
1120
+ const cookies = parseCookies(c.req.header("Cookie"));
1121
+ const accessToken = cookies[HUBSPOT_ACCESS_TOKEN_COOKIE_NAME];
1122
+ const clientId = hubspotConnectEnv.isCimdEnabled ? buildCimdClientIdUrlFromRequest({
1123
+ requestUrl: c.req.url,
1124
+ basePath,
1125
+ xForwardedProto,
1126
+ xForwardedHost,
1127
+ requestHostHeader
1128
+ }) : hubspotConnectEnv.hubspotClientId;
1129
+ const revokeEndpointUrl = new URL("/oauth/v1/revoke", hubspotConnectEnv.hubspotOAuthApiOrigin).href;
1130
+ if (accessToken) if (hubspotConnectEnv.isCimdEnabled) {
1131
+ if (!appKeys) return c.json({ error: "Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD is enabled" }, 500);
1132
+ const clientAssertion = await buildClientAssertion({
1133
+ appKeys,
1134
+ clientId,
1135
+ audience: revokeEndpointUrl
1136
+ });
1137
+ await revokeToken({
1138
+ revokeEndpointUrl,
1139
+ body: new URLSearchParams({
1140
+ token: accessToken,
1141
+ token_type_hint: "access_token",
1142
+ client_id: clientId,
1143
+ client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
1144
+ client_assertion: clientAssertion
1145
+ }),
1146
+ logger
1147
+ });
1148
+ } else await revokeToken({
1149
+ revokeEndpointUrl,
1150
+ body: new URLSearchParams({
1151
+ token: accessToken,
1152
+ token_type_hint: "access_token",
1153
+ client_id: clientId,
1154
+ client_secret: hubspotConnectEnv.hubspotClientSecret
1155
+ }),
1156
+ logger
1157
+ });
1158
+ setResponseCookie({
1159
+ c,
1160
+ value: serializeCookie({
1161
+ name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,
1162
+ value: "",
1163
+ path: "/",
1164
+ sameSite: "None",
1165
+ partitioned: true,
1166
+ maxAge: 0
1167
+ })
1168
+ });
1169
+ setResponseCookie({
1170
+ c,
1171
+ value: serializeCookie({
1172
+ name: HUBSPOT_APP_SID_COOKIE_NAME,
1173
+ value: "",
1174
+ path: "/",
1175
+ sameSite: "None",
1176
+ partitioned: true,
1177
+ maxAge: 0
1178
+ })
1179
+ });
1180
+ setResponseCookie({
1181
+ c,
1182
+ value: serializeCookie({
1183
+ name: HUBSPOT_APP_ORIGIN_COOKIE_NAME,
1184
+ value: "",
1185
+ path: "/",
1186
+ sameSite: "None",
1187
+ partitioned: true,
1188
+ maxAge: 0
1189
+ })
1190
+ });
1191
+ Object.keys(cookies).forEach((cookieName) => {
1192
+ if (cookieName.startsWith("hs_refresh_")) setResponseCookie({
1193
+ c,
1194
+ value: serializeCookie({
1195
+ name: cookieName,
1196
+ value: "",
1197
+ path: refreshCookiePath,
1198
+ sameSite: "None",
1199
+ partitioned: true,
1200
+ maxAge: 0
1201
+ })
1202
+ });
1203
+ });
1204
+ return c.json({ redirect_to: "/" });
1205
+ }
1206
+ //#endregion
1207
+ //#region src/server/hono/hubspot-connect-routes/auth-refresh.ts
1208
+ async function handleAuthRefresh(c, options) {
1209
+ const { appKeys, refreshCookiePath, basePath, hubspotConnectEnv } = options;
1210
+ const xForwardedProto = c.req.header("x-forwarded-proto") ?? void 0;
1211
+ const xForwardedHost = c.req.header("x-forwarded-host") ?? void 0;
1212
+ const requestHostHeader = c.req.header("host") ?? void 0;
1213
+ const cookies = parseCookies(c.req.header("Cookie"));
1214
+ const sessionId = cookies[HUBSPOT_APP_SID_COOKIE_NAME];
1215
+ if (!sessionId) return c.json({ error: "Missing session cookie" }, 401);
1216
+ if (hubspotConnectEnv.isAppPrivateKeyRequired && !appKeys) return c.json({ error: "Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD or DPoP is enabled" }, 500);
1217
+ const sidHash = await sha256base64url(sessionId);
1218
+ const refreshCookieName = `${HUBSPOT_REFRESH_COOKIE_PREFIX}${sidHash}`;
1219
+ const refreshToken = cookies[refreshCookieName];
1220
+ if (!refreshToken) return c.json({ error: "Missing refresh token" }, 401);
1221
+ const clientId = hubspotConnectEnv.isCimdEnabled ? buildCimdClientIdUrlFromRequest({
1222
+ requestUrl: c.req.url,
1223
+ basePath,
1224
+ xForwardedProto,
1225
+ xForwardedHost,
1226
+ requestHostHeader
1227
+ }) : hubspotConnectEnv.hubspotClientId;
1228
+ const tokenEndpointUrl = new URL("/oauth/v1/token", hubspotConnectEnv.hubspotOAuthApiOrigin).href;
1229
+ let dpopProof;
1230
+ if (hubspotConnectEnv.isDpopEnabled) dpopProof = await buildTokenEndpointDpopProof({
1231
+ appKeys,
1232
+ tokenEndpointUrl,
1233
+ sessionIdHash: sidHash
1234
+ });
1235
+ let formParams;
1236
+ if (hubspotConnectEnv.isCimdEnabled) formParams = {
1237
+ grant_type: "refresh_token",
1238
+ refresh_token: refreshToken,
1239
+ ...buildClientAssertionFormParams({
1240
+ clientId,
1241
+ clientAssertion: await buildClientAssertion({
1242
+ appKeys,
1243
+ clientId,
1244
+ audience: tokenEndpointUrl
1245
+ })
1246
+ })
1247
+ };
1248
+ else formParams = {
1249
+ grant_type: "refresh_token",
1250
+ refresh_token: refreshToken,
1251
+ ...buildClientSecretFormParams({
1252
+ clientId,
1253
+ clientSecret: hubspotConnectEnv.hubspotClientSecret
1254
+ })
1255
+ };
1256
+ const tokenResult = await requestOAuthToken({
1257
+ tokenEndpointUrl,
1258
+ isDpopEnabled: hubspotConnectEnv.isDpopEnabled,
1259
+ ...dpopProof !== void 0 ? { dpopProof } : {},
1260
+ formParams
1261
+ });
1262
+ if (!tokenResult.ok) return c.json({ error: `Token refresh failed: ${tokenResult.errorText}` }, 502);
1263
+ const { access_token: newAccessToken, refresh_token: newRefreshToken, expires_in } = tokenResult.body;
1264
+ if (!newRefreshToken) return c.json({ error: "Token response missing refresh_token" }, 502);
1265
+ if (!isPositiveFiniteNumber(expires_in)) return c.json({ error: "Token response missing or invalid expires_in" }, 502);
1266
+ setResponseCookie({
1267
+ c,
1268
+ value: serializeCookie({
1269
+ name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,
1270
+ value: newAccessToken,
1271
+ path: "/",
1272
+ sameSite: "None",
1273
+ partitioned: true,
1274
+ maxAge: expires_in
1275
+ })
1276
+ });
1277
+ setResponseCookie({
1278
+ c,
1279
+ value: serializeCookie({
1280
+ name: refreshCookieName,
1281
+ value: newRefreshToken,
1282
+ path: refreshCookiePath,
1283
+ sameSite: "None",
1284
+ partitioned: true,
1285
+ maxAge: REFRESH_COOKIE_MAX_AGE_SEC
1286
+ })
1287
+ });
1288
+ Object.keys(cookies).forEach((cookieName) => {
1289
+ if (cookieName.startsWith("hs_refresh_") && cookieName !== refreshCookieName) setResponseCookie({
1290
+ c,
1291
+ value: serializeCookie({
1292
+ name: cookieName,
1293
+ value: "",
1294
+ path: refreshCookiePath,
1295
+ sameSite: "None",
1296
+ partitioned: true,
1297
+ maxAge: 0
1298
+ })
1299
+ });
1300
+ });
1301
+ return c.json({ expires_in });
1302
+ }
1303
+ //#endregion
1304
+ //#region src/server/hono/hubspot-connect-routes/cimd-public-routes.ts
1305
+ async function handleCimdClientJson(c, options) {
1306
+ const { cimdClientMetadata, basePath } = options;
1307
+ if (!cimdClientMetadata) return c.text("CIMD client metadata is not configured", 500);
1308
+ const xForwardedProto = c.req.header("x-forwarded-proto") ?? void 0;
1309
+ const xForwardedHost = c.req.header("x-forwarded-host") ?? void 0;
1310
+ const requestHostHeader = c.req.header("host") ?? void 0;
1311
+ const forwarded = {
1312
+ requestUrl: c.req.url,
1313
+ basePath,
1314
+ xForwardedProto,
1315
+ xForwardedHost,
1316
+ requestHostHeader
1317
+ };
1318
+ const body = {
1319
+ redirect_uri: buildOAuthRedirectUriFromRequest(forwarded),
1320
+ jwks_uri: buildHubSpotAppJwksUrlFromRequest(forwarded),
1321
+ scope: cimdClientMetadata.scope
1322
+ };
1323
+ return c.text(JSON.stringify(body, null, 2), 200, { "Content-Type": "application/json; charset=utf-8" });
1324
+ }
1325
+ async function handleCimdAppJwks(c, options) {
1326
+ const { appKeys, hubspotConnectEnv } = options;
1327
+ if (!hubspotConnectEnv.isCimdEnabled) return c.text("Not found", 404);
1328
+ if (!appKeys) return c.text("Missing app keys", 503);
1329
+ const kid = await getJwkThumbprint({ publicKeyJwk: appKeys.appPublicKeyJwk });
1330
+ const jwks = { keys: [{
1331
+ ...appKeys.appPublicKeyJwk,
1332
+ kid,
1333
+ use: "sig",
1334
+ alg: "ES256",
1335
+ key_ops: ["verify"],
1336
+ ext: true
1337
+ }] };
1338
+ return c.json(jwks);
1339
+ }
1340
+ //#endregion
1341
+ //#region src/server/hono/hubspot-connect-routes/hubspot-connect-routes.ts
1342
+ /**
1343
+ * Mounts hubspot-connect routes: OAuth (`/auth/...`); `GET /client.json`
1344
+ * from `cimdClientMetadata`; `GET /jwks.json` when CIMD is enabled.
1345
+ */
1346
+ function registerHubSpotConnectRoutes(options) {
1347
+ const { app, appKeys, basePath, hubspotConnectEnv, cimdClientMetadata, logger = noopLogger } = options;
1348
+ if (!cimdClientMetadata) throw new Error("registerHubSpotConnectRoutes: cimdClientMetadata is required");
1349
+ assertHubSpotConnectCimdClientMetadata(cimdClientMetadata);
1350
+ const oauthRouteOptions = {
1351
+ appKeys,
1352
+ refreshCookiePath: `${basePath}/auth`,
1353
+ logger,
1354
+ basePath,
1355
+ hubspotConnectEnv,
1356
+ cimdClientMetadata
1357
+ };
1358
+ app.use("*", corsMiddleware());
1359
+ app.get("/client.json", (c) => handleCimdClientJson(c, oauthRouteOptions));
1360
+ if (hubspotConnectEnv.isCimdEnabled) app.get("/jwks.json", (c) => handleCimdAppJwks(c, oauthRouteOptions));
1361
+ app.get("/auth/init-session", (c) => handleAuthInitSession(c, oauthRouteOptions));
1362
+ app.post("/auth/complete", (c) => handleAuthComplete(c, oauthRouteOptions));
1363
+ app.post("/auth/refresh", (c) => handleAuthRefresh(c, oauthRouteOptions));
1364
+ app.post("/auth/logout", (c) => handleAuthLogout(c, oauthRouteOptions));
1365
+ }
1366
+ //#endregion
1367
+ //#region src/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.ts
1368
+ /**
1369
+ * Reads hubspot-connect environment variables from `process.env` or
1370
+ * `Deno.env` and returns a typed object for
1371
+ * {@link registerHubSpotConnectRoutes}.
1372
+ */
1373
+ function loadHubSpotConnectRoutesEnv() {
1374
+ const hubspotAuthorizationEndpoint = requireEnv("HUBSPOT_AUTHORIZATION_ENDPOINT");
1375
+ const hubspotOAuthApiOrigin = new URL(requireEnv("HUBSPOT_OAUTH_API_ORIGIN")).origin;
1376
+ const isCimdEnabled = isHubspotCimdEnabled();
1377
+ const isDpopEnabled = isHubspotDpopEnabled();
1378
+ const isAppPrivateKeyRequired = isCimdEnabled || isDpopEnabled;
1379
+ if (isCimdEnabled) return {
1380
+ hubspotAuthorizationEndpoint,
1381
+ hubspotOAuthApiOrigin,
1382
+ isCimdEnabled: true,
1383
+ isDpopEnabled,
1384
+ isAppPrivateKeyRequired
1385
+ };
1386
+ return {
1387
+ hubspotAuthorizationEndpoint,
1388
+ hubspotOAuthApiOrigin,
1389
+ isCimdEnabled: false,
1390
+ isDpopEnabled,
1391
+ isAppPrivateKeyRequired,
1392
+ hubspotClientId: requireEnv("HUBSPOT_CLIENT_ID"),
1393
+ hubspotClientSecret: requireEnv("HUBSPOT_CLIENT_SECRET")
1394
+ };
1395
+ }
1396
+ //#endregion
1397
+ //#region src/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.ts
1398
+ const PORT$1 = Deno.env.get("PORT");
1399
+ const serveOptions$1 = typeof PORT$1 === "string" ? { port: parseInt(PORT$1, 10) } : {};
1400
+ const HUBSPOT_CONNECT_BASE_PATH = "/functions/v1/hubspot-connect";
1401
+ function runHubSpotConnectLovableServer(options) {
1402
+ const { appKeys, cimdClientMetadata } = options;
1403
+ const hubspotConnectEnv = loadHubSpotConnectRoutesEnv();
1404
+ const result = Deno.serve(serveOptions$1, (request) => {
1405
+ const app = new Hono();
1406
+ registerHubSpotConnectRoutes({
1407
+ app: app.basePath(HUBSPOT_CONNECT_BASE_PATH),
1408
+ appKeys,
1409
+ basePath: HUBSPOT_CONNECT_BASE_PATH,
1410
+ hubspotConnectEnv,
1411
+ cimdClientMetadata
1412
+ });
1413
+ return app.fetch(request);
1414
+ });
1415
+ console.log(`[hubspot-connect] Listening on ${result.addr.port}`);
1416
+ return Promise.resolve();
1417
+ }
1418
+ //#endregion
1419
+ //#region src/server/lovable/hubspot-connect/index.ts
1420
+ /**
1421
+ * Lovable-style entry point for the hubspot-connect Deno function.
1422
+ * Loads `HUBSPOT_APP_PRIVATE_KEY` via `secureStart`, then serves OAuth
1423
+ * and CIMD routes under `/functions/v1/hubspot-connect`.
1424
+ */
1425
+ async function startHubSpotConnectFunction(options) {
1426
+ assertHubSpotConnectCimdClientMetadata(options.client);
1427
+ await secureStart(async () => ({ start: (context) => runHubSpotConnectLovableServer({
1428
+ ...context,
1429
+ cimdClientMetadata: options.client
1430
+ }) }));
1431
+ }
1432
+ //#endregion
1433
+ //#region src/server/lovable/create-app-function-start.ts
1434
+ const PORT = Deno.env.get("PORT");
1435
+ const serveOptions = typeof PORT === "string" ? { port: parseInt(PORT, 10) } : {};
1436
+ /**
1437
+ * Builds a Deno-style `start({ appKeys })` entry point that boots a
1438
+ * Hono app under `basePath`, wires the SDK's per-request HubSpot
1439
+ * proxy via `createAppConnectRequestHandler`, and serves it with
1440
+ * `Deno.serve` on `PORT`.
1441
+ */
1442
+ function createAppFunctionStart(options) {
1443
+ const { basePath, registerRoutes, logger } = options;
1444
+ return ({ appKeys }) => {
1445
+ Deno.serve(serveOptions, createAppConnectRequestHandler({
1446
+ appKeys,
1447
+ ...logger !== void 0 ? { logger } : {},
1448
+ registerRoutes: (app) => {
1449
+ registerRoutes(app.basePath(basePath));
1450
+ }
1451
+ }));
1452
+ console.log(`[app-function ${basePath}] Listening on http://localhost:${PORT}`);
1453
+ return Promise.resolve();
1454
+ };
1455
+ }
1456
+ //#endregion
4
1457
  export { createAppFunctionStart, secureStart, startHubSpotConnectFunction };
1458
+
1459
+ //# sourceMappingURL=lovable.js.map