@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lovable.js","names":["PORT","serveOptions"],"sources":["../../src/server/import-app-keys.ts","../../src/server/utils/env-utils.ts","../../src/server/secure-start-core.ts","../../src/server/deno/start.ts","../../src/server/hono/hubspot-connect-routes/cimd-client-metadata-types.ts","../../src/shared/logger.ts","../../src/server/api-client-core/plugins/fetch-transport.ts","../../src/server/constants.ts","../../src/server/proxy.ts","../../src/server/utils/cookie-utils.ts","../../src/server/sanitize-request.ts","../../src/server/hono/utils/cors-middleware.ts","../../src/server/hono/hono-request-handler.ts","../../src/shared/constants.ts","../../src/server/hono/utils/cookie-utils.ts","../../src/server/hono/hubspot-connect-routes/constants.ts","../../src/server/hono/hubspot-connect-routes/oauth-client.ts","../../src/server/hono/hubspot-connect-routes/utils.ts","../../src/server/hono/hubspot-connect-routes/auth-complete.ts","../../src/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.ts","../../src/server/hono/hubspot-connect-routes/auth-init-session.ts","../../src/server/hono/hubspot-connect-routes/auth-logout.ts","../../src/server/hono/hubspot-connect-routes/auth-refresh.ts","../../src/server/hono/hubspot-connect-routes/cimd-public-routes.ts","../../src/server/hono/hubspot-connect-routes/hubspot-connect-routes.ts","../../src/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.ts","../../src/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.ts","../../src/server/lovable/hubspot-connect/index.ts","../../src/server/lovable/create-app-function-start.ts"],"sourcesContent":["import type { AppKeys } from './types.ts';\nimport { base64StandardToArrayBuffer } from './utils/base64-utils.ts';\n\n/**\n * Imports a base64-encoded PKCS8 ES256 private key into the\n * `AppKeys` shape used throughout the SDK.\n *\n * The function imports the key twice: once as **extractable** to\n * derive the public JWK (via `crypto.subtle.exportKey`), and once\n * as **non-extractable** so the long-lived `appPrivateKey` can never\n * be exfiltrated.\n *\n * @throws {Error} When `envKey` is empty/undefined or when the key\n * isn't an EC P-256 keypair.\n */\nexport async function importAppKeys(\n envKey: string | undefined\n): Promise<AppKeys> {\n const b64 = envKey?.trim() ?? '';\n if (!b64) {\n throw new Error('HUBSPOT_APP_PRIVATE_KEY is not set');\n }\n\n const pkcs8 = base64StandardToArrayBuffer(b64);\n const tempPrivateKey = await crypto.subtle.importKey(\n 'pkcs8',\n pkcs8,\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['sign']\n );\n const privateJwk = await crypto.subtle.exportKey('jwk', tempPrivateKey);\n if (\n privateJwk.kty !== 'EC' ||\n privateJwk.crv !== 'P-256' ||\n typeof privateJwk.x !== 'string' ||\n typeof privateJwk.y !== 'string'\n ) {\n throw new Error('Expected P-256 EC private key JWK with x and y');\n }\n const appPublicKeyJwk: JsonWebKey = {\n kty: 'EC',\n crv: 'P-256',\n x: privateJwk.x,\n y: privateJwk.y,\n };\n const appPrivateKey = await crypto.subtle.importKey(\n 'pkcs8',\n pkcs8,\n { name: 'ECDSA', namedCurve: 'P-256' },\n false,\n ['sign']\n );\n return { appPrivateKey, appPublicKeyJwk };\n}\n","interface GlobalWithOptionalEnv {\n process?: { env?: Record<string, string | undefined> };\n Deno?: { env: { get(name: string): string | undefined } };\n}\n\n/**\n * Reads an environment variable in a way that works under both Node\n * (`process.env`) and Deno (`Deno.env.get`). Returns `undefined` when\n * the variable is unset or when neither runtime is available.\n */\nexport function getEnv(key: string): string | undefined {\n const g = globalThis as GlobalWithOptionalEnv;\n const proc = g.process;\n if (proc?.env) {\n return proc.env[key];\n }\n const deno = g.Deno;\n if (deno !== undefined) {\n return deno.env.get(key);\n }\n return undefined;\n}\n\n/**\n * Reads an environment variable and throws when it is missing or empty.\n * Use for values the SDK cannot fall back on (e.g. upstream service\n * URLs).\n *\n * @throws {Error} When the environment variable is unset or an empty\n * string.\n */\nexport function requireEnv(key: string): string {\n const value = getEnv(key);\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n}\n\n/**\n * Whether outbound HubSpot OAuth and API calls should attach DPoP on\n * the wire. Disabled only when `HUBSPOT_DPOP_ENABLED` is exactly the\n * string `\"false\"` (unset or any other value keeps DPoP enabled).\n */\nexport function isHubspotDpopEnabled(): boolean {\n return getEnv('HUBSPOT_DPOP_ENABLED') !== 'false';\n}\n\n/**\n * Whether the SDK should use CIMD-style OAuth (client ID URL + JWT client\n * assertion). Disabled only when `HUBSPOT_CIMD_ENABLED` is exactly the\n * string `\"false\"` (unset or any other value keeps CIMD enabled).\n */\nexport function isHubspotCimdEnabled(): boolean {\n return getEnv('HUBSPOT_CIMD_ENABLED') !== 'false';\n}\n\n/**\n * Whether `HUBSPOT_APP_PRIVATE_KEY` must be set for `secureStart`. False\n * when both CIMD and DPoP are disabled — the SDK then uses\n * `client_secret` for OAuth and Bearer tokens only for API calls.\n */\nexport function isHubspotAppPrivateKeyRequired(): boolean {\n return isHubspotCimdEnabled() || isHubspotDpopEnabled();\n}\n","import { importAppKeys } from './import-app-keys.ts';\nimport type { AppKeys } from './types.ts';\nimport { isHubspotAppPrivateKeyRequired } from './utils/env-utils.ts';\n\n/**\n * Context passed to a function-style entrypoint loaded by `runSecureStart`.\n * Contains imported `AppKeys` when CIMD or DPoP is enabled; otherwise\n * `null` (traditional OAuth with `client_secret` and Bearer API calls).\n */\nexport interface SecureStartContext {\n appKeys: AppKeys | null;\n}\n\ninterface SecureEntryPointExports {\n start: (context: SecureStartContext) => Promise<void>;\n}\n\n/**\n * Loader returned to `runSecureStart` that produces the entrypoint\n * module. Always pass an `() => import('...')` arrow so the bundler\n * preserves dynamic-import semantics.\n */\nexport type SecureStartLoader = () => Promise<SecureEntryPointExports>;\n\n/**\n * Platform adapters injected by the runtime-specific shim\n * (`node/start.ts` or `deno/start.ts`). Keeping the env/exit/delete\n * functions out of the core lets the shared logic stay platform-free.\n */\nexport interface SecureStartAdapter {\n /** Reads the named env var, or returns `undefined` when unset. */\n readEnv: (key: string) => string | undefined;\n /** Removes the named env var so child processes cannot read it. */\n deleteEnv: (key: string) => void;\n /** Terminates the process with the given exit code. */\n exit: (code: number) => never;\n}\n\nconst APP_PRIVATE_KEY_ENV = 'HUBSPOT_APP_PRIVATE_KEY';\n\n/**\n * Loads `HUBSPOT_APP_PRIVATE_KEY` when CIMD or DPoP is enabled, deletes\n * it from the environment so later code cannot re-read it, imports the\n * entrypoint module via `loader`, and invokes `start` with `AppKeys` or\n * `null` when both features are off. On failure, logs the error and\n * exits with code 1.\n */\nexport async function runSecureStart(\n loader: SecureStartLoader,\n adapter: SecureStartAdapter\n): Promise<void> {\n let appKeys: AppKeys | null = null;\n if (isHubspotAppPrivateKeyRequired()) {\n const envKey = adapter.readEnv(APP_PRIVATE_KEY_ENV)?.trim();\n if (!envKey) {\n throw new Error(`${APP_PRIVATE_KEY_ENV} is not set`);\n }\n appKeys = await importAppKeys(envKey);\n adapter.deleteEnv(APP_PRIVATE_KEY_ENV);\n }\n\n const exports = await loader();\n return exports.start({ appKeys }).catch((error) => {\n console.error(error);\n return adapter.exit(1);\n });\n}\n","import {\n runSecureStart,\n type SecureStartAdapter,\n type SecureStartContext,\n type SecureStartLoader,\n} from '../secure-start-core.ts';\n\nexport type { SecureStartContext, SecureStartLoader };\n\nconst denoSecureStartAdapter: SecureStartAdapter = {\n readEnv: (key) => Deno.env.get(key),\n deleteEnv: (key) => {\n Deno.env.delete(key);\n },\n exit: (code) => Deno.exit(code),\n};\n\n/**\n * Deno entrypoint helper. Reads `HUBSPOT_APP_PRIVATE_KEY` from `Deno.env`\n * when CIMD or DPoP is enabled, imports the supplied loader, and invokes\n * `start` with `AppKeys` or `null`.\n */\nexport function secureStart(loader: SecureStartLoader): Promise<void> {\n return runSecureStart(loader, denoSecureStartAdapter);\n}\n","/**\n * Caller-supplied scope configuration for the CIMD document served at\n * `{basePath}/client.json`. `redirect_uri` and `jwks_uri` are derived at\n * request time by the hubspot-connect routes.\n */\nexport interface HubSpotConnectCimdClientMetadata {\n scope: HubSpotConnectCimdClientScope;\n}\n\nexport interface HubSpotConnectCimdClientScope {\n required: string[];\n optional?: string[];\n}\n\n/**\n * JSON body returned by `GET {basePath}/client.json` (HubSpot CIMD).\n */\nexport interface HubSpotConnectCimdClientDocument {\n redirect_uri: string;\n jwks_uri: string;\n scope: HubSpotConnectCimdClientScope;\n}\n\nexport function assertHubSpotConnectCimdClientMetadata(\n value: HubSpotConnectCimdClientMetadata\n): void {\n const required = value.scope?.required;\n const requiredOk =\n Array.isArray(required) &&\n required.length > 0 &&\n required.every((s) => typeof s === 'string' && s.length > 0);\n if (!requiredOk) {\n throw new Error(\n 'HubSpotConnectCimdClientMetadata.scope.required must be a non-empty array of non-empty strings'\n );\n }\n const optional = value.scope.optional;\n if (optional === undefined) {\n return;\n }\n if (!Array.isArray(optional)) {\n throw new Error(\n 'HubSpotConnectCimdClientMetadata.scope.optional must be an array when set'\n );\n }\n if (\n optional.length > 0 &&\n !optional.every((s) => typeof s === 'string' && s.length > 0)\n ) {\n throw new Error(\n 'HubSpotConnectCimdClientMetadata.scope.optional entries must be non-empty strings'\n );\n }\n}\n","/**\n * Pluggable logger contract used by the SDK on both the browser and\n * server. Consumers can pass `console`-like loggers, structured\n * loggers (pino / winston / etc.) or no-op stubs in tests.\n */\nexport interface Logger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\nfunction formatPrefix(name: string): string {\n return `[${name}]`;\n}\n\n/**\n * Creates a console-backed logger that prefixes every line with the\n * supplied `name`. Used as the default when no custom logger is\n * provided.\n */\nexport function createLogger(name: string): Logger {\n const prefix = formatPrefix(name);\n return {\n debug: (message, ...args) => {\n console.debug(prefix, message, ...args);\n },\n info: (message, ...args) => {\n console.info(prefix, message, ...args);\n },\n warn: (message, ...args) => {\n console.warn(prefix, message, ...args);\n },\n error: (message, ...args) => {\n console.error(prefix, message, ...args);\n },\n };\n}\n\n/**\n * Logger that swallows every message. Convenient for tests and for\n * the SDK's server-side handlers when no logger is provided by the\n * host application.\n */\nexport const noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n","import { isBinaryData } from '../binary-data.ts';\nimport type { Plugin } from '../types.ts';\n\nconst BASE_URL = 'https://api.hubapi.com';\n\nexport interface FetchTransportPluginOptions {\n getAccessToken: () => string;\n}\n\nfunction appendRecordToUrlSearchParams(\n params: URLSearchParams,\n record: Record<string, unknown>\n): void {\n for (const [key, value] of Object.entries(record)) {\n if (value == null) continue;\n if (Array.isArray(value)) {\n for (const item of value) {\n params.append(key, String(item as string));\n }\n } else {\n params.append(key, String(value));\n }\n }\n}\n\n/**\n * Transport plugin that executes HTTP requests using the Fetch API.\n *\n * This is the terminal middleware in the chain — it builds the actual HTTP\n * request from the operation descriptor and returns a normalized response.\n * It handles path-parameter interpolation, query-string serialization,\n * Bearer-token auth, and content-type negotiation (JSON, form-urlencoded, multipart).\n */\nexport function fetchTransportPlugin(\n options: FetchTransportPluginOptions\n): Plugin {\n return {\n activate(api) {\n api.addMiddleware(async (ctx) => {\n const { operation } = ctx;\n\n // Interpolate path parameters (e.g. \"/contacts/{contactId}\" → \"/contacts/123\")\n let url = `${BASE_URL}${operation.path}`;\n if (operation.pathParams) {\n for (const [key, value] of Object.entries(operation.pathParams)) {\n url = url.replace(`{${key}}`, encodeURIComponent(String(value)));\n }\n }\n\n // Serialize query parameters, supporting repeated keys for array values\n if (operation.queryParams) {\n const params = new URLSearchParams();\n appendRecordToUrlSearchParams(params, operation.queryParams);\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n ...(operation.headers ?? {}),\n Authorization: `Bearer ${options.getAccessToken()}`,\n };\n\n const init: RequestInit = {\n method: operation.method.toUpperCase(),\n headers,\n };\n\n // For file uploads the API expects multipart/form-data; BinaryData\n // values are appended as Blobs while everything else is stringified.\n // Form bodies use application/x-www-form-urlencoded. Otherwise JSON.\n if (operation.contentType === 'multipart/form-data' && operation.body) {\n const formData = new FormData();\n for (const [key, value] of Object.entries(\n operation.body as Record<string, unknown>\n )) {\n if (value == null) continue;\n if (isBinaryData(value)) {\n formData.append(key, value.source as Blob);\n } else {\n formData.append(key, String(value));\n }\n }\n init.body = formData;\n } else if (\n operation.contentType === 'application/x-www-form-urlencoded'\n ) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n if (operation.body) {\n const params = new URLSearchParams();\n appendRecordToUrlSearchParams(\n params,\n operation.body as Record<string, unknown>\n );\n const encoded = params.toString();\n if (encoded) init.body = encoded;\n }\n } else {\n headers['Content-Type'] = 'application/json';\n if (operation.body) {\n init.body = JSON.stringify(operation.body);\n }\n }\n const response = await fetch(url, init);\n const responseHeaders: Record<string, string> = Object.create(null);\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n // 204 No Content responses have no body to parse\n bodyJson: response.status === 204 ? undefined : await response.json(),\n };\n });\n },\n };\n}\n","/**\n * Cookie name carrying the DPoP-bound access token. Uses the\n * `__Host-` prefix so the browser only accepts it from a `Secure`\n * response with `Path=/` — a defense-in-depth against subdomain\n * cookie injection.\n */\nexport const HUBSPOT_ACCESS_TOKEN_COOKIE_NAME = '__Host-hs_access_token';\n\n/**\n * Cookie carrying the opaque app-session ID. Hashed before being put\n * on the wire as a DPoP `sid` claim.\n */\nexport const HUBSPOT_APP_SID_COOKIE_NAME = '__Host-hs_app_sid';\n\n/**\n * Cookie pinning the browser-facing app origin (e.g.\n * `https://app.example.com`) for the lifetime of an app session.\n * Set by `auth/init-session` from the request's `Origin` header and\n * read by:\n *\n * - The CORS middleware to emit a credentialed\n * `Access-Control-Allow-Origin` value (`*` is forbidden when\n * `Access-Control-Allow-Credentials: true`).\n * - `auth/complete` to rebuild the OAuth `redirect_uri` it sent to\n * HubSpot during `init-session` (the token endpoint validates that\n * the two values match).\n *\n * `__Host-` prefixed (Path=/, Secure, no Domain), so the same\n * function host can serve both `hubspot-connect` and `api` routes\n * and read the cookie from either.\n */\nexport const HUBSPOT_APP_ORIGIN_COOKIE_NAME = '__Host-hs_app_origin';\n\n/**\n * Prefix used for refresh-token cookies. Each session gets its own\n * cookie name (`hs_refresh_<sidHash>`) so multiple devices/tabs can\n * coexist without overwriting each other's refresh tokens.\n */\nexport const HUBSPOT_REFRESH_COOKIE_PREFIX = 'hs_refresh_';\n\nconst PROTECTED_COOKIE_NAMES = new Set([\n HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n HUBSPOT_APP_SID_COOKIE_NAME,\n HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n]);\n\n/**\n * Returns `true` for cookies the SDK manages internally\n * (access token, session ID, any refresh-token cookie). The\n * `sanitizeRequest` helper uses this to strip these cookies from the\n * request before user code sees it, ensuring user route handlers\n * cannot accidentally leak them in logs or proxy them upstream.\n */\nexport function isProtectedCookieName(cookieName: string): boolean {\n return (\n PROTECTED_COOKIE_NAMES.has(cookieName) ||\n cookieName.startsWith(HUBSPOT_REFRESH_COOKIE_PREFIX)\n );\n}\n\n/**\n * Cookie carrying the PKCE code verifier between `init-session` and\n * `auth/complete`. Set with `SameSite=None; Secure; Partitioned` so the\n * frontend's credentialed cross-site `POST /auth/complete` (made from\n * the OAuth callback page on the app origin to the SDK's edge function\n * origin) carries it through. `Lax` would silently drop it on that\n * fetch, breaking every successful HubSpot redirect.\n */\nexport const TEMP_COOKIE_PKCE_VERIFIER = '__hs_pkce_verifier';\n\n/**\n * Cookie carrying the OAuth `state` value between `init-session` and\n * `auth/complete`. Compared against the `state` query parameter as the\n * primary CSRF defense. Same `SameSite=None; Secure; Partitioned`\n * attributes as `TEMP_COOKIE_PKCE_VERIFIER` for the same cross-site\n * `POST /auth/complete` reason.\n */\nexport const TEMP_COOKIE_OAUTH_STATE = '__hs_oauth_state';\n","import { noopLogger, type Logger } from '../shared/logger.ts';\nimport {\n type AppKeys,\n type HubSpotProxy,\n type HubSpotProxyRequest,\n type UserCredentials,\n} from './types.ts';\nimport { sha256base64url } from './utils/crypto-utils.ts';\nimport { signDpopProof } from './utils/dpop-utils.ts';\nimport { isHubspotDpopEnabled, requireEnv } from './utils/env-utils.ts';\n\nconst HUBSPOT_API_ORIGIN = requireEnv('HUBSPOT_API_ORIGIN');\n\n/**\n * Options accepted by {@link createHubSpotProxy}.\n */\nexport interface CreateHubSpotProxyOptions {\n /**\n * User session context from the incoming browser request.\n */\n userCredentials: UserCredentials;\n\n /**\n * Imported app keys from `secureStart`, or `null` when CIMD and DPoP\n * are both disabled.\n */\n appKeys: AppKeys | null;\n /** Optional logger. Defaults to a no-op logger. */\n logger?: Logger;\n}\n\nconst notAuthenticated: HubSpotProxy = {\n authenticated: false,\n fetch: async (): Promise<Response> => {\n return new Response(null, {\n status: 401,\n statusText: 'Unauthorized',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n },\n};\n\nconst EMPTY_HEADERS = {};\n\nexport function createHubSpotProxy(\n options: CreateHubSpotProxyOptions\n): HubSpotProxy {\n const { userCredentials, appKeys, logger = noopLogger } = options;\n\n if (isHubspotDpopEnabled() && appKeys === null) {\n throw new Error(\n 'createHubSpotProxy: appKeys is required when HUBSPOT_DPOP_ENABLED is not false'\n );\n }\n\n const { accessToken, sessionId } = userCredentials;\n\n if (!accessToken || !sessionId) {\n logger.debug(\n 'createHubSpotProxy: returning unauthenticated proxy (missing cookies)'\n );\n return notAuthenticated;\n }\n\n async function proxyFetch(request: HubSpotProxyRequest): Promise<Response> {\n const { path, method = 'GET', headers = EMPTY_HEADERS, body } = request;\n\n const targetUrl = `${HUBSPOT_API_ORIGIN}${path}`;\n const useDpop = isHubspotDpopEnabled();\n\n let authorizationHeaders: Record<string, string>;\n if (useDpop) {\n const ath = await sha256base64url(accessToken!);\n const sid = await sha256base64url(sessionId!);\n const dpopProof = await signDpopProof({\n appKeys: appKeys!,\n claims: {\n htm: method,\n htu: targetUrl,\n jti: crypto.randomUUID(),\n iat: Math.floor(Date.now() / 1000),\n ath,\n sid,\n },\n });\n authorizationHeaders = {\n Authorization: `DPoP ${accessToken}`,\n DPoP: dpopProof,\n };\n } else {\n authorizationHeaders = {\n Authorization: `Bearer ${accessToken}`,\n };\n }\n\n const finalHeaders = { ...headers, ...authorizationHeaders };\n\n const requestInit: RequestInit = {\n headers: finalHeaders,\n method,\n };\n\n if (body != null) {\n requestInit.body = body;\n }\n\n return fetch(targetUrl, requestInit);\n }\n\n return {\n authenticated: true,\n fetch: proxyFetch,\n };\n}\n","/**\n * Parses an HTTP `Cookie` request header into a `name -> value` map.\n * Tolerates leading/trailing whitespace, missing `=` (treats the\n * cookie value as empty), and duplicate names (last write wins).\n *\n * Returns an empty object when `cookieHeader` is `null`/`undefined`\n * /empty so callers don't have to null-check the input.\n */\nexport function parseCookies(\n cookieHeader: string | null | undefined\n): Record<string, string> {\n if (!cookieHeader) return {};\n return Object.fromEntries(\n cookieHeader\n .split(';')\n .map((pair) => {\n const eqIdx = pair.indexOf('=');\n if (eqIdx === -1) return [pair.trim(), ''] as [string, string];\n return [pair.slice(0, eqIdx).trim(), pair.slice(eqIdx + 1).trim()] as [\n string,\n string,\n ];\n })\n .filter(([name]) => name.length > 0)\n );\n}\n","import { isProtectedCookieName } from './constants.ts';\nimport { parseCookies } from './utils/cookie-utils.ts';\n\nfunction serializeCookies(cookies: Map<string, string>): string {\n const parts: string[] = [];\n for (const [name, value] of cookies) {\n parts.push(`${name}=${value}`);\n }\n return parts.join('; ');\n}\n\n/**\n * Mutates `headers` in place: parses the `Cookie` header, drops every\n * protected cookie (see {@link isProtectedCookieName}), and rewrites\n * the header. Deletes the header entirely when nothing survives.\n *\n * Used by the SDK's auth middleware after it has read the access\n * token / session ID, so user route handlers never see — and\n * therefore cannot leak — those cookies, while CORS / auth\n * middleware that ran first still got the raw values.\n */\nexport function stripProtectedCookies(headers: Headers): void {\n const cookies = parseCookies(headers.get('Cookie'));\n const surviving = new Map<string, string>();\n for (const [name, value] of Object.entries(cookies)) {\n if (!isProtectedCookieName(name)) {\n surviving.set(name, value);\n }\n }\n\n if (surviving.size === 0) {\n headers.delete('cookie');\n } else {\n headers.set('cookie', serializeCookies(surviving));\n }\n}\n\n/**\n * Returns a clone of `original` whose `Cookie` header has every\n * protected cookie removed (see {@link isProtectedCookieName}). When\n * no other cookies remain, the header is dropped entirely.\n *\n * Standalone helper retained for callers that want a new Request\n * (e.g. tests). Inside the SDK's per-request handler, the auth\n * middleware uses {@link stripProtectedCookies} directly on\n * `c.req.raw.headers` so the auth check itself can still read the\n * protected cookies before they are stripped.\n */\nexport function sanitizeRequest(original: Request): Request {\n const headers = new Headers(original.headers);\n stripProtectedCookies(headers);\n\n const init: RequestInit = {\n method: original.method,\n headers,\n redirect: original.redirect,\n signal: original.signal,\n };\n\n if (original.body !== null) {\n init.body = original.body;\n (init as RequestInit & { duplex: 'half' }).duplex = 'half';\n }\n\n return new Request(original.url, init);\n}\n","import type { Context, MiddlewareHandler } from 'hono';\n\nimport { HUBSPOT_APP_ORIGIN_COOKIE_NAME } from '../../constants.ts';\nimport { parseCookies } from '../../utils/cookie-utils.ts';\n\n/**\n * Comma-separated list of request headers the SDK accepts on\n * cross-site fetches. Mirrors the Supabase Edge Functions defaults\n * the Lovable AI agent emits today, plus `content-type` for the\n * `auth/complete` POST body and `accept` so JSON content negotiation\n * works.\n */\nconst ALLOWED_HEADERS = [\n 'authorization',\n 'x-client-info',\n 'apikey',\n 'content-type',\n 'accept',\n 'x-supabase-client-platform',\n 'x-supabase-client-platform-version',\n 'x-supabase-client-runtime',\n 'x-supabase-client-runtime-version',\n].join(', ');\n\nconst ALLOWED_METHODS = 'GET, POST, OPTIONS';\n\nconst PREFLIGHT_MAX_AGE_SECONDS = '600';\n\n/**\n * Reads the persisted app-origin cookie from the request, falling\n * back to the literal `Origin` request header. The cookie is the\n * authoritative pin once `auth/init-session` has run; on the very\n * first init-session call (no cookie yet) we just echo whatever\n * `Origin` the caller sent — the actual access decision is enforced\n * by cookie-based authentication on every other route, not by CORS.\n */\nfunction resolveAllowedOrigin(c: Context): string | null {\n const cookies = parseCookies(c.req.header('Cookie'));\n const pinned = cookies[HUBSPOT_APP_ORIGIN_COOKIE_NAME];\n if (pinned) return pinned;\n return c.req.header('Origin') ?? null;\n}\n\nfunction setSharedCorsHeaders(c: Context, allowOrigin: string): void {\n c.res.headers.set('Access-Control-Allow-Origin', allowOrigin);\n c.res.headers.set('Access-Control-Allow-Credentials', 'true');\n // `Origin` so caches differentiate per-caller responses; `Cookie`\n // because the allowed origin is derived from the persisted\n // `__Host-hs_app_origin` cookie.\n c.res.headers.set('Vary', 'Origin, Cookie');\n}\n\n/**\n * Hono middleware that emits credentialed CORS response headers for\n * the cross-origin Lovable / Supabase deployment shape.\n *\n * - On `OPTIONS` preflight: short-circuits with a 204 carrying\n * `Access-Control-Allow-*` headers. The browser will then send the\n * real request with cookies attached.\n * - On every other method: echoes the pinned `__Host-hs_app_origin`\n * cookie value (or, before init-session has run, the request\n * `Origin` header) as `Access-Control-Allow-Origin`, with\n * `Access-Control-Allow-Credentials: true`. The wildcard `*` is\n * forbidden by browsers when credentials are included, so the\n * middleware always echoes a concrete origin.\n *\n * Skips header emission entirely when the request has no `Origin`\n * (server-to-server calls, curl, etc.) so non-browser callers are\n * left untouched.\n */\nexport function corsMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n const allowOrigin = resolveAllowedOrigin(c);\n\n if (c.req.method === 'OPTIONS') {\n const headers = new Headers();\n if (allowOrigin) {\n headers.set('Access-Control-Allow-Origin', allowOrigin);\n headers.set('Access-Control-Allow-Credentials', 'true');\n headers.set('Vary', 'Origin, Cookie');\n }\n headers.set('Access-Control-Allow-Methods', ALLOWED_METHODS);\n headers.set('Access-Control-Allow-Headers', ALLOWED_HEADERS);\n headers.set('Access-Control-Max-Age', PREFLIGHT_MAX_AGE_SECONDS);\n return new Response(null, { status: 204, headers });\n }\n\n await next();\n\n if (allowOrigin) {\n setSharedCorsHeaders(c, allowOrigin);\n }\n return;\n };\n}\n","import { Hono } from 'hono';\n\nimport { noopLogger, type Logger } from '../../shared/logger.ts';\nimport { createHubSpotClient } from '../api-client-core/client.ts';\nimport { fetchTransportPlugin } from '../api-client-core/plugins/fetch-transport.ts';\nimport {\n HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n HUBSPOT_APP_SID_COOKIE_NAME,\n} from '../constants.ts';\nimport { createHubSpotProxy } from '../proxy.ts';\nimport { sanitizeRequest } from '../sanitize-request.ts';\nimport type { AppKeys, UserCredentials } from '../types.ts';\nimport { parseCookies } from '../utils/cookie-utils.ts';\nimport type { AppConnectHonoBindings, AppConnectHonoEnv } from './types.ts';\nimport { corsMiddleware } from './utils/cors-middleware.ts';\n\n/**\n * Web-standard fetch handler signature returned by\n * {@link createAppConnectRequestHandler}.\n */\nexport type AppConnectFetchHandler = (\n request: Request\n) => Response | Promise<Response>;\n\n/**\n * Callback used to attach application routes to the SDK-owned Hono\n * app instance.\n */\nexport type RegisterAppConnectRoutesFunction = (\n app: Hono<AppConnectHonoEnv>\n) => void;\n\n/**\n * Options accepted by {@link createAppConnectRequestHandler}.\n */\nexport interface CreateAppConnectRequestHandlerOptions {\n /** Registers application routes on the SDK-owned Hono app. */\n registerRoutes: RegisterAppConnectRoutesFunction;\n /**\n * Imported app keys from `secureStart`, or `null` when CIMD and DPoP\n * are both disabled.\n */\n appKeys: AppKeys | null;\n /**\n * Optional logger. When omitted the SDK uses a no-op logger so\n * server-side state never leaks into the host application's\n * console.\n */\n logger?: Logger;\n}\n\n/**\n * Wraps a Hono app so its `fetch` handler additionally:\n *\n * - Strips SDK-managed cookies (access token, refresh, sid) from the\n * request before the app sees them, via `sanitizeRequest`.\n * - Exposes a `hubSpotProxy` on the Hono context so route handlers\n * can issue authenticated calls to HubSpot's API on behalf of the\n * browser session.\n */\nexport function createAppConnectRequestHandler(\n options: CreateAppConnectRequestHandlerOptions\n): AppConnectFetchHandler {\n const { registerRoutes, appKeys, logger = noopLogger } = options;\n const app = new Hono<AppConnectHonoEnv>();\n // Credentialed CORS first: preflights short-circuit with 204\n // before the auth check runs, and 401 responses still carry\n // `Access-Control-Allow-*` headers (the browser drops responses\n // without them on credentialed cross-site fetches).\n app.use('*', corsMiddleware());\n\n // Auth gate: every non-OPTIONS request must arrive with the\n // SDK-managed access-token + session-id cookies. The CORS\n // middleware above short-circuits OPTIONS, so this only runs on\n // real requests; missing cookies now surface as a normal 401 with\n // CORS headers attached on the way back out (the previous\n // implementation threw on a missing `Cookie` header before any\n // middleware ran, which broke browser preflights).\n app.use('*', async (c, next) => {\n const { authenticated } = c.env.hubSpot;\n if (!authenticated) {\n return c.json({ error: 'Unauthorized' }, 401);\n }\n\n await next();\n return;\n });\n\n registerRoutes(app);\n\n return (request: Request) => {\n const cookie = request.headers.get('Cookie');\n if (!cookie) {\n throw new Error('Missing auth cookies');\n }\n const cookies = parseCookies(cookie);\n const accessToken = cookies[HUBSPOT_ACCESS_TOKEN_COOKIE_NAME];\n const sessionId = cookies[HUBSPOT_APP_SID_COOKIE_NAME];\n\n const userCredentials: UserCredentials = { accessToken, sessionId };\n\n const proxy = createHubSpotProxy({\n userCredentials,\n appKeys,\n logger,\n });\n\n const client = createHubSpotClient({\n plugins: [\n fetchTransportPlugin({\n getAccessToken: () => {\n if (!accessToken) {\n throw new Error('Missing access token');\n }\n return accessToken;\n },\n }),\n ],\n });\n\n const sanitizedRequest = sanitizeRequest(request);\n\n const honoBindings: AppConnectHonoBindings = {\n hubSpot: {\n proxy,\n client,\n authenticated: proxy.authenticated,\n },\n };\n\n return app.fetch(sanitizedRequest, honoBindings);\n };\n}\n","/**\n * Constants whose values are part of the contract between the browser\n * controller and the server-side hubspot-connect routes. Both halves\n * import from this module so the wire format stays in sync.\n */\n\n/**\n * Query parameter on the OAuth return URL that carries the new access\n * token's expiry (Unix epoch milliseconds). The browser controller\n * sets this in the URL after a successful `auth/complete` call and\n * then strips it during `initAppConnect` via `history.replaceState`.\n */\nexport const EXPIRES_AT_URL_PARAM = '__hs_expires_at';\n\n/**\n * Path the browser visits after HubSpot's authorize endpoint\n * redirects back to the app. Mounted on the **frontend** origin (not\n * the SDK's edge function host) so all OAuth-related cookies live in\n * the `(frontend, edge)` CHIPS partition.\n *\n * The SDK's `auth/init-session` builds the OAuth `redirect_uri` as\n * `${requestOrigin}${HUBSPOT_FRONTEND_CALLBACK_PATH}`. The browser\n * controller, on `start()`, recognizes this path on `window.location`\n * and forwards `?code` + `?state` to the SDK's `auth/complete`\n * endpoint via a credentialed cross-site fetch. The host app must\n * register `${app_origin}${HUBSPOT_FRONTEND_CALLBACK_PATH}` as a\n * redirect URI in its HubSpot app settings.\n */\nexport const HUBSPOT_FRONTEND_CALLBACK_PATH = '/__hubspot_oauth_callback';\n\n/**\n * Query parameter on the `auth/complete` POST request carrying the\n * authorization `code` HubSpot returned to the frontend callback.\n */\nexport const AUTH_COMPLETE_CODE_PARAM = 'code';\n\n/**\n * Query parameter on the `auth/complete` POST request carrying the\n * OAuth `state` HubSpot echoed back to the frontend callback.\n */\nexport const AUTH_COMPLETE_STATE_PARAM = 'state';\n","import type { Context } from 'hono';\n\nexport interface SetResponseCookieOptions {\n c: Context;\n value: string;\n}\n\n/**\n * Appends a `Set-Cookie` header to the response. Hono replaces single\n * headers by default, so this uses `{ append: true }` to emit multiple\n * cookies on the same response.\n */\nexport function setResponseCookie(options: SetResponseCookieOptions): void {\n const { c, value } = options;\n c.header('Set-Cookie', value, { append: true });\n}\n\nexport interface SerializeCookieOptions {\n name: string;\n value: string;\n /** `__Host-` prefix requires `Path=/` and is recommended for session cookies. */\n path: string;\n /**\n * Defaults to `Strict`.\n *\n * - `Strict`: only sent on same-site requests. Default for self-hosted\n * same-origin deployments.\n * - `Lax`: also sent on top-level cross-site GET navigations. Use for\n * short-lived OAuth temp cookies that need to survive a redirect.\n * - `None`: sent on all cross-site requests; **requires `Secure=true`\n * and is typically combined with `Partitioned=true`** for the\n * cross-origin Lovable / Supabase deployment shape.\n */\n sameSite?: 'Strict' | 'Lax' | 'None';\n /** Lifetime in seconds. `0` deletes the cookie. */\n maxAge: number;\n /** Defaults to `true`; only set `false` for tests or non-HTTPS dev hosts. */\n secure?: boolean;\n /** Defaults to `true`. */\n httpOnly?: boolean;\n /**\n * When `true`, appends the `Partitioned` attribute (CHIPS — Cookies\n * Having Independent Partitioned State). The browser then keys the\n * cookie by `(top-level site, cookie host)` instead of by cookie\n * host alone, which is required for the cross-origin SDK shape\n * where the React app and the SDK's edge functions live on\n * different sites and third-party cookies are blocked.\n *\n * Defaults to `false`. Browsers ignore `Partitioned` on cookies\n * without `Secure=true` and reject it on cookies without\n * `SameSite=None`.\n */\n partitioned?: boolean;\n}\n\n/**\n * Builds a `Set-Cookie` header value with HubSpot's default attributes\n * (HttpOnly, Secure, SameSite). Centralizes the serialization so all\n * cookies share the same policy.\n */\nexport function serializeCookie(options: SerializeCookieOptions): string {\n const {\n name,\n value,\n path,\n sameSite = 'Strict',\n maxAge,\n secure = true,\n httpOnly = true,\n partitioned = false,\n } = options;\n const parts: string[] = [`${name}=${value}`];\n if (httpOnly) parts.push('HttpOnly');\n if (secure) parts.push('Secure');\n parts.push(`SameSite=${sameSite}`);\n parts.push(`Path=${path}`);\n parts.push(`Max-Age=${maxAge}`);\n if (partitioned) parts.push('Partitioned');\n return parts.join('; ');\n}\n","export const SESSION_MAX_AGE_SEC = 2592000;\nexport const OAUTH_TEMP_MAX_AGE_SEC = 3600;\nexport const REFRESH_COOKIE_MAX_AGE_SEC = 2592000;\n","import type { AppKeys } from '../../types.ts';\nimport { signDpopProof } from '../../utils/dpop-utils.ts';\nimport { signJwt } from '../../utils/jwt-utils.ts';\n\n/**\n * Lifetime of the OAuth `client_assertion` JWT in seconds. Short by\n * design — RFC 7521 recommends short-lived assertions, and HubSpot's\n * authorization server rejects assertions older than ~5 minutes.\n */\nconst CLIENT_ASSERTION_TTL_SEC = 60;\n\n/**\n * The `client_assertion_type` value mandated by RFC 7523 §2.2 for\n * JWT-bearer client authentication.\n */\nconst JWT_BEARER_ASSERTION_TYPE =\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';\n\n/**\n * Wire shape of a HubSpot OAuth token-endpoint success response.\n */\nexport interface OAuthTokenResponse {\n /** New DPoP-bound access token (sender-constrained). */\n access_token: string;\n /** New refresh token, opaque to the client. */\n refresh_token: string;\n /** Lifetime of `access_token` in seconds. */\n expires_in: number;\n}\n\nexport interface BuildClientAssertionOptions {\n appKeys: AppKeys;\n /** Client ID URL — used as both `iss` and `sub`. */\n clientId: string;\n /** Token-endpoint URL — used as `aud`. */\n audience: string;\n}\n\n/**\n * Mints a short-lived ES256 JWT used as the `client_assertion`\n * parameter when calling HubSpot's token endpoint, per RFC 7523.\n */\nexport async function buildClientAssertion(\n options: BuildClientAssertionOptions\n): Promise<string> {\n const { appKeys, clientId, audience } = options;\n return signJwt({\n privateKey: appKeys.appPrivateKey,\n payload: {\n iss: clientId,\n sub: clientId,\n aud: audience,\n jti: crypto.randomUUID(),\n },\n ttlSeconds: CLIENT_ASSERTION_TTL_SEC,\n });\n}\n\nexport interface BuildTokenEndpointDpopProofOptions {\n appKeys: AppKeys;\n /** Token-endpoint URL — used as the DPoP `htu` claim. */\n tokenEndpointUrl: string;\n /** Hash of the app session ID — used as the DPoP `sid` claim. */\n sessionIdHash: string;\n}\n\n/**\n * Signs a DPoP proof for a `POST` to HubSpot's token endpoint. RFC 9449\n * binds the resulting access token to the proving public key so that\n * later API calls must come from the same key holder.\n */\nexport async function buildTokenEndpointDpopProof(\n options: BuildTokenEndpointDpopProofOptions\n): Promise<string> {\n const { appKeys, tokenEndpointUrl, sessionIdHash } = options;\n return signDpopProof({\n appKeys,\n claims: {\n htm: 'POST',\n htu: tokenEndpointUrl,\n jti: crypto.randomUUID(),\n iat: Math.floor(Date.now() / 1000),\n sid: sessionIdHash,\n },\n });\n}\n\nexport interface RequestOAuthTokenOptions {\n tokenEndpointUrl: string;\n /** Body parameters; serialized to `application/x-www-form-urlencoded`. */\n formParams: Record<string, string>;\n /**\n * When true, a `DPoP` header is required and `dpopProof` must be set.\n */\n isDpopEnabled: boolean;\n /**\n * DPoP proof for this request; required when `isDpopEnabled` is true.\n */\n dpopProof?: string;\n}\n\nexport interface RequestOAuthTokenSuccess {\n ok: true;\n body: OAuthTokenResponse;\n}\n\nexport interface RequestOAuthTokenFailure {\n ok: false;\n /** HTTP status returned by the upstream endpoint. */\n status: number;\n /** Error body as text — used to compose the SDK's error response. */\n errorText: string;\n}\n\nexport type RequestOAuthTokenResult =\n | RequestOAuthTokenSuccess\n | RequestOAuthTokenFailure;\n\n/**\n * POSTs an `application/x-www-form-urlencoded` body to a HubSpot token\n * endpoint. Attaches a `DPoP` header when `isDpopEnabled` is true and\n * `dpopProof` is provided. Reads the response once — either\n * as JSON on success or as text on failure — so callers never have to\n * consume the body twice.\n */\nexport async function requestOAuthToken(\n options: RequestOAuthTokenOptions\n): Promise<RequestOAuthTokenResult> {\n const { tokenEndpointUrl, formParams, dpopProof, isDpopEnabled } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n if (isDpopEnabled) {\n if (!dpopProof) {\n throw new Error('DPoP proof is required when DPoP is enabled');\n }\n headers.DPoP = dpopProof;\n }\n const tokenResponse = await fetch(tokenEndpointUrl, {\n method: 'POST',\n headers,\n body: new URLSearchParams(formParams),\n });\n if (!tokenResponse.ok) {\n const errorText = await tokenResponse.text();\n return { ok: false, status: tokenResponse.status, errorText };\n }\n const body = (await tokenResponse.json()) as OAuthTokenResponse;\n return { ok: true, body };\n}\n\n/**\n * Form parameters always present on the OAuth `client_assertion` flow.\n * Spread into the call site's `formParams`.\n */\nexport function buildClientAssertionFormParams(input: {\n clientId: string;\n clientAssertion: string;\n}): Record<string, string> {\n const { clientId, clientAssertion } = input;\n return {\n client_id: clientId,\n client_assertion_type: JWT_BEARER_ASSERTION_TYPE,\n client_assertion: clientAssertion,\n };\n}\n\nexport interface BuildClientSecretFormParamsOptions {\n clientId: string;\n clientSecret: string;\n}\n\nexport function buildClientSecretFormParams(\n options: BuildClientSecretFormParamsOptions\n): Record<string, string> {\n const { clientId, clientSecret } = options;\n return {\n client_id: clientId,\n client_secret: clientSecret,\n };\n}\n","import { HUBSPOT_FRONTEND_CALLBACK_PATH } from '../../../shared/constants.ts';\nimport { serializeCookie } from '../utils/cookie-utils.ts';\n\nexport function clearTempCookie(name: string): string {\n return serializeCookie({\n name,\n value: '',\n path: '/',\n sameSite: 'None',\n maxAge: 0,\n partitioned: true,\n });\n}\n\n/**\n * Parses the request `Origin` header into the canonical origin\n * string (`URL.origin`) or returns `null` when the header is\n * missing, malformed, or carries a scheme/host the SDK does not\n * accept.\n *\n * Accepted shapes:\n *\n * - `https://<host>` for production deployments.\n * - `http://localhost[:<port>]` and `http://127.0.0.1[:<port>]`\n * for local development; browsers exempt these from the `Secure`\n * cookie restriction.\n *\n * Rejects values with a path/query/hash component (the request\n * `Origin` header is by spec a bare origin, so anything else\n * indicates a malformed or hostile request).\n */\nexport function parseAppOriginHeader(\n originHeader: string | undefined\n): string | null {\n if (!originHeader) return null;\n let parsed: URL;\n try {\n parsed = new URL(originHeader);\n } catch {\n return null;\n }\n if (parsed.pathname !== '/' && parsed.pathname !== '') return null;\n if (parsed.search !== '' || parsed.hash !== '') return null;\n if (parsed.protocol === 'https:') return parsed.origin;\n if (\n parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')\n ) {\n return parsed.origin;\n }\n return null;\n}\n\n/**\n * OAuth `redirect_uri` for the cross-origin app shape: the OAuth\n * callback lands on the **frontend** origin (not the SDK's edge\n * function host), so all cookies set by `init-session` and read by\n * `auth/complete` live in the same `(frontend, edge)` CHIPS\n * partition.\n *\n * Used by `auth/init-session` (when building `authorization_url`)\n * and `auth/complete` (which must rebuild the same value to satisfy\n * the OAuth token endpoint's `redirect_uri` check).\n */\nexport function buildFrontendOAuthRedirectUri(appOrigin: string): string {\n return `${appOrigin}${HUBSPOT_FRONTEND_CALLBACK_PATH}`;\n}\n\nexport function isSafeReturnPath(rawPath: string): boolean {\n if (!rawPath.startsWith('/')) return false;\n if (rawPath.includes('\\0')) return false;\n let decoded: string;\n try {\n decoded = decodeURIComponent(rawPath);\n } catch {\n return false;\n }\n if (!decoded.startsWith('/')) return false;\n const second = decoded.charAt(1);\n if (second === '/' || second === '\\\\') return false;\n return true;\n}\n\nexport function getRequestHost(requestUrl: string): string {\n return new URL(requestUrl).host;\n}\n\nexport interface GetRequestHostForHubspotConnectOptions {\n requestUrl: string;\n xForwardedHost?: string | undefined;\n /** `Host` when `X-Forwarded-Host` is absent (some proxies only set `X-Forwarded-Proto`). */\n requestHostHeader?: string | undefined;\n}\n\n/**\n * Host for CIMD `client_id` URLs when hubspot-connect sits behind a reverse\n * proxy (e.g. Vite → Deno): prefers `X-Forwarded-Host`, then `Host`, then the\n * request URL host.\n */\nexport function getRequestHostForHubspotConnect(\n options: GetRequestHostForHubspotConnectOptions\n): string {\n const rawForwarded = options.xForwardedHost?.split(',')[0]?.trim();\n if (rawForwarded) {\n try {\n return new URL(`https://${rawForwarded}`).host;\n } catch {\n /* invalid forwarded host */\n }\n }\n const rawHost = options.requestHostHeader?.split(',')[0]?.trim();\n if (rawHost) {\n try {\n return new URL(`https://${rawHost}`).host;\n } catch {\n /* invalid host header */\n }\n }\n return getRequestHost(options.requestUrl);\n}\n\nexport interface BuildOAuthRedirectUriFromRequestOptions {\n requestUrl: string;\n basePath: string;\n xForwardedProto?: string | undefined;\n xForwardedHost?: string | undefined;\n /** `Host` when `X-Forwarded-Host` is absent but `X-Forwarded-Proto` is set. */\n requestHostHeader?: string | undefined;\n}\n\nfunction normalizeHubSpotConnectBasePath(basePath: string): string {\n return basePath.endsWith('/') && basePath.length > 1\n ? basePath.slice(0, -1)\n : basePath;\n}\n\n/**\n * Public origin for hubspot-connect URLs (`redirect_uri`, CIMD `client_id`,\n * `jwks_uri`). Matches the host/proto rules used for the OAuth callback.\n */\nexport function buildHubSpotConnectRequestOrigin(\n options: BuildOAuthRedirectUriFromRequestOptions\n): string {\n const { requestUrl, xForwardedProto, xForwardedHost, requestHostHeader } =\n options;\n const proto = xForwardedProto?.split(',')[0]?.trim();\n if (proto && (proto === 'http' || proto === 'https')) {\n const forwardedHost = xForwardedHost?.split(',')[0]?.trim();\n const hostHeader = requestHostHeader?.split(',')[0]?.trim();\n const hostPart = forwardedHost || hostHeader || new URL(requestUrl).host;\n return `${proto}://${hostPart}`;\n }\n return new URL(requestUrl).origin;\n}\n\n/**\n * OAuth `redirect_uri` for the hubspot-connect callback. Uses\n * `X-Forwarded-Proto` with `X-Forwarded-Host`, then `Host`, then the request URL\n * host when the proto is forwarded (reverse proxy); otherwise the request URL\n * origin.\n */\nexport function buildOAuthRedirectUriFromRequest(\n options: BuildOAuthRedirectUriFromRequestOptions\n): string {\n const trimmed = normalizeHubSpotConnectBasePath(options.basePath);\n const origin = buildHubSpotConnectRequestOrigin(options);\n return `${origin}${trimmed}/auth/callback`;\n}\n\n/**\n * CIMD `client_id` URL: `{origin}{basePath}/client.json`.\n */\nexport function buildCimdClientIdUrlFromRequest(\n options: BuildOAuthRedirectUriFromRequestOptions\n): string {\n const trimmed = normalizeHubSpotConnectBasePath(options.basePath);\n const origin = buildHubSpotConnectRequestOrigin(options);\n return `${origin}${trimmed}/client.json`;\n}\n\n/**\n * App JWKS URL published in CIMD: `{origin}{basePath}/jwks.json`.\n */\nexport function buildHubSpotAppJwksUrlFromRequest(\n options: BuildOAuthRedirectUriFromRequestOptions\n): string {\n const trimmed = normalizeHubSpotConnectBasePath(options.basePath);\n const origin = buildHubSpotConnectRequestOrigin(options);\n return `${origin}${trimmed}/jwks.json`;\n}\n\nexport function isPositiveFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0;\n}\n","import type { Context } from 'hono';\n\nimport {\n AUTH_COMPLETE_CODE_PARAM,\n AUTH_COMPLETE_STATE_PARAM,\n} from '../../../shared/constants.ts';\nimport {\n HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n HUBSPOT_REFRESH_COOKIE_PREFIX,\n TEMP_COOKIE_OAUTH_STATE,\n TEMP_COOKIE_PKCE_VERIFIER,\n} from '../../constants.ts';\nimport { base64urlDecode } from '../../utils/base64-utils.ts';\nimport { parseCookies } from '../../utils/cookie-utils.ts';\nimport { serializeCookie, setResponseCookie } from '../utils/cookie-utils.ts';\nimport { REFRESH_COOKIE_MAX_AGE_SEC } from './constants.ts';\nimport {\n buildClientAssertion,\n buildClientAssertionFormParams,\n buildClientSecretFormParams,\n buildTokenEndpointDpopProof,\n requestOAuthToken,\n} from './oauth-client.ts';\nimport type { HubSpotConnectOAuthRouteOptions } from './types.ts';\nimport {\n buildCimdClientIdUrlFromRequest,\n buildFrontendOAuthRedirectUri,\n clearTempCookie,\n isPositiveFiniteNumber,\n isSafeReturnPath,\n parseAppOriginHeader,\n} from './utils.ts';\n\ninterface OAuthStatePayload {\n return_path?: string;\n sid?: string;\n}\n\n/**\n * Cross-origin OAuth completion endpoint.\n *\n * Called from the React app on the frontend OAuth callback path\n * (`HUBSPOT_FRONTEND_CALLBACK_PATH`) once HubSpot has redirected the\n * browser back with `?code` + `?state`. The browser POSTs both\n * values here as a credentialed cross-site fetch — same partition as\n * `init-session`, so the temp PKCE/state cookies are visible — and\n * the SDK:\n *\n * 1. Validates `state` against the temp `__hs_oauth_state` cookie.\n * 2. Pulls the PKCE verifier from `__hs_pkce_verifier`.\n * 3. Rebuilds the same `redirect_uri` it sent to HubSpot during\n * `init-session` (frontend origin + the fixed callback path);\n * the OAuth token endpoint requires the two values to match.\n * 4. Exchanges `code` for an access + refresh token (with DPoP /\n * CIMD client-assertion when enabled).\n * 5. Sets the durable session cookies (access token, refresh) with\n * `SameSite=None; Secure; Partitioned` so they live in the\n * `(frontend, edge)` partition where subsequent API fetches will\n * read them.\n * 6. Clears the temp cookies.\n * 7. Returns `{ expires_at, return_path }` so the controller can\n * update its session-storage expiry tracking and navigate back to\n * the page the user started the connect flow from.\n */\nexport async function handleAuthComplete(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n) {\n const { appKeys, refreshCookiePath, hubspotConnectEnv } = options;\n const xForwardedProto = c.req.header('x-forwarded-proto') ?? undefined;\n const xForwardedHost = c.req.header('x-forwarded-host') ?? undefined;\n const requestHostHeader = c.req.header('host') ?? undefined;\n const code = c.req.query(AUTH_COMPLETE_CODE_PARAM);\n const state = c.req.query(AUTH_COMPLETE_STATE_PARAM);\n\n if (!code || !state) {\n return c.json({ error: 'Missing code or state' }, 400);\n }\n\n if (hubspotConnectEnv.isAppPrivateKeyRequired && !appKeys) {\n return c.json(\n {\n error:\n 'Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD or DPoP is enabled',\n },\n 500\n );\n }\n\n const cookies = parseCookies(c.req.header('Cookie'));\n const expectedState = cookies[TEMP_COOKIE_OAUTH_STATE];\n const codeVerifier = cookies[TEMP_COOKIE_PKCE_VERIFIER];\n const appOriginCookie = cookies[HUBSPOT_APP_ORIGIN_COOKIE_NAME];\n\n if (!expectedState || state !== decodeURIComponent(expectedState)) {\n return c.json({ error: 'State mismatch' }, 403);\n }\n if (!codeVerifier) {\n return c.json({ error: 'Missing PKCE verifier' }, 400);\n }\n // The redirect_uri the OAuth token endpoint validates must equal\n // the one we sent during init-session. We rebuild it from the\n // pinned origin cookie so that value is anchored server-side, not\n // taken from the (caller-controlled) request `Origin` on this call.\n const appOrigin = parseAppOriginHeader(appOriginCookie);\n if (!appOrigin) {\n return c.json({ error: 'Missing app origin cookie' }, 400);\n }\n\n let statePayload: OAuthStatePayload;\n try {\n statePayload = JSON.parse(\n new TextDecoder().decode(base64urlDecode(decodeURIComponent(state)))\n ) as OAuthStatePayload;\n } catch {\n return c.json({ error: 'Malformed state value' }, 400);\n }\n const returnPath = statePayload.return_path;\n if (!returnPath || !isSafeReturnPath(returnPath)) {\n return c.json({ error: 'Invalid return path in state' }, 400);\n }\n\n const sessionId = statePayload.sid;\n if (!sessionId) {\n return c.json({ error: 'Missing app session cookie' }, 400);\n }\n\n const decodedCodeVerifier = decodeURIComponent(codeVerifier);\n\n const clientId = hubspotConnectEnv.isCimdEnabled\n ? buildCimdClientIdUrlFromRequest({\n requestUrl: c.req.url,\n basePath: options.basePath,\n xForwardedProto,\n xForwardedHost,\n requestHostHeader,\n })\n : hubspotConnectEnv.hubspotClientId;\n\n const redirectUri = buildFrontendOAuthRedirectUri(appOrigin);\n\n const tokenEndpointUrl = new URL(\n '/oauth/v1/token',\n hubspotConnectEnv.hubspotOAuthApiOrigin\n ).href;\n\n let dpopProof: string | undefined;\n if (hubspotConnectEnv.isDpopEnabled) {\n dpopProof = await buildTokenEndpointDpopProof({\n appKeys: appKeys!,\n tokenEndpointUrl,\n sessionIdHash: sessionId,\n });\n }\n\n let formParams: Record<string, string>;\n if (hubspotConnectEnv.isCimdEnabled) {\n const clientAssertion = await buildClientAssertion({\n appKeys: appKeys!,\n clientId,\n audience: tokenEndpointUrl,\n });\n formParams = {\n grant_type: 'authorization_code',\n code,\n code_verifier: decodedCodeVerifier,\n redirect_uri: redirectUri,\n ...buildClientAssertionFormParams({ clientId, clientAssertion }),\n };\n } else {\n formParams = {\n grant_type: 'authorization_code',\n code,\n code_verifier: decodedCodeVerifier,\n redirect_uri: redirectUri,\n ...buildClientSecretFormParams({\n clientId,\n clientSecret: hubspotConnectEnv.hubspotClientSecret,\n }),\n };\n }\n\n const tokenResult = await requestOAuthToken({\n tokenEndpointUrl,\n isDpopEnabled: hubspotConnectEnv.isDpopEnabled,\n ...(dpopProof !== undefined ? { dpopProof } : {}),\n formParams,\n });\n if (!tokenResult.ok) {\n return c.json(\n { error: `Token exchange failed: ${tokenResult.errorText}` },\n 502\n );\n }\n\n const {\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_in,\n } = tokenResult.body;\n if (!refreshToken) {\n return c.json({ error: 'Token response missing refresh_token' }, 502);\n }\n if (!isPositiveFiniteNumber(expires_in)) {\n return c.json(\n { error: 'Token response missing or invalid expires_in' },\n 502\n );\n }\n\n const expiresAt = Date.now() + expires_in * 1000;\n const refreshCookieName = `${HUBSPOT_REFRESH_COOKIE_PREFIX}${sessionId}`;\n\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n value: accessToken,\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: expires_in,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: refreshCookieName,\n value: refreshToken,\n path: refreshCookiePath,\n sameSite: 'None',\n partitioned: true,\n maxAge: REFRESH_COOKIE_MAX_AGE_SEC,\n }),\n });\n setResponseCookie({ c, value: clearTempCookie(TEMP_COOKIE_PKCE_VERIFIER) });\n setResponseCookie({ c, value: clearTempCookie(TEMP_COOKIE_OAUTH_STATE) });\n\n return c.json({ expires_at: expiresAt, return_path: returnPath });\n}\n","import type { HubSpotConnectCimdClientMetadata } from './cimd-client-metadata-types.ts';\n\nexport interface DeriveHubSpotAuthorizeScopesFromClientMetadataSuccess {\n ok: true;\n scope: string;\n optionalScope?: string;\n}\n\nexport interface DeriveHubSpotAuthorizeScopesFromClientMetadataFailure {\n ok: false;\n status: number;\n message: string;\n}\n\nexport type DeriveHubSpotAuthorizeScopesFromClientMetadataResult =\n | DeriveHubSpotAuthorizeScopesFromClientMetadataSuccess\n | DeriveHubSpotAuthorizeScopesFromClientMetadataFailure;\n\n/**\n * Builds `scope` and `optional_scope` query values for HubSpot\n * `/oauth/authorize` from in-memory client metadata (same shape as\n * `HubSpotConnectCimdClientMetadata` / `startHubSpotConnectFunction({ client })`).\n */\nexport function deriveHubSpotAuthorizeScopesFromClientMetadata(\n metadata: HubSpotConnectCimdClientMetadata\n): DeriveHubSpotAuthorizeScopesFromClientMetadataResult {\n const required = metadata.scope?.required;\n const requiredOk =\n Array.isArray(required) &&\n required.length > 0 &&\n required.every((s) => typeof s === 'string' && s.length > 0);\n\n if (!requiredOk) {\n return {\n ok: false,\n status: 500,\n message: 'Invalid or empty scope.required in client metadata',\n };\n }\n\n const scope = required.join(' ');\n\n const optionalRaw = metadata.scope.optional;\n if (optionalRaw == null) {\n return { ok: true, scope };\n }\n\n if (!Array.isArray(optionalRaw)) {\n return {\n ok: false,\n status: 500,\n message: 'Invalid scope.optional in client metadata',\n };\n }\n\n if (optionalRaw.length === 0) {\n return { ok: true, scope };\n }\n\n if (!optionalRaw.every((s) => typeof s === 'string' && s.length > 0)) {\n return {\n ok: false,\n status: 500,\n message: 'Invalid scope.optional in client metadata',\n };\n }\n\n return {\n ok: true,\n scope,\n optionalScope: optionalRaw.join(' '),\n };\n}\n","import type { Context } from 'hono';\n\nimport {\n HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n HUBSPOT_APP_SID_COOKIE_NAME,\n TEMP_COOKIE_OAUTH_STATE,\n TEMP_COOKIE_PKCE_VERIFIER,\n} from '../../constants.ts';\nimport { base64url } from '../../utils/base64-utils.ts';\nimport { sha256base64url } from '../../utils/crypto-utils.ts';\nimport { serializeCookie, setResponseCookie } from '../utils/cookie-utils.ts';\nimport { OAUTH_TEMP_MAX_AGE_SEC, SESSION_MAX_AGE_SEC } from './constants.ts';\nimport { deriveHubSpotAuthorizeScopesFromClientMetadata } from './fetch-hubspot-client-metadata.ts';\nimport type { HubSpotConnectOAuthRouteOptions } from './types.ts';\nimport {\n buildCimdClientIdUrlFromRequest,\n buildFrontendOAuthRedirectUri,\n isSafeReturnPath,\n parseAppOriginHeader,\n} from './utils.ts';\n\nexport async function handleAuthInitSession(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n) {\n const { hubspotConnectEnv, cimdClientMetadata } = options;\n const xForwardedProto = c.req.header('x-forwarded-proto') ?? undefined;\n const xForwardedHost = c.req.header('x-forwarded-host') ?? undefined;\n const requestHostHeader = c.req.header('host') ?? undefined;\n const url = new URL(c.req.url);\n const returnPath = url.searchParams.get('return_path') ?? '/';\n if (!isSafeReturnPath(returnPath)) {\n return c.text('Invalid return_path', 400);\n }\n\n // The app origin pins the OAuth `redirect_uri` (which lands on the\n // frontend, not on this edge function) and, via the persisted\n // `__Host-hs_app_origin` cookie, drives credentialed\n // `Access-Control-Allow-Origin` on every subsequent SDK response.\n const appOrigin = parseAppOriginHeader(c.req.header('Origin'));\n if (!appOrigin) {\n return c.text(\n 'Missing or invalid Origin header; init-session must be called from a browser',\n 400\n );\n }\n\n const sessionIdBytes = new Uint8Array(32);\n crypto.getRandomValues(sessionIdBytes);\n const sessionId = base64url(sessionIdBytes);\n const sessionIdHash = await sha256base64url(sessionId);\n\n const codeVerifierBytes = new Uint8Array(32);\n crypto.getRandomValues(codeVerifierBytes);\n const codeVerifier = base64url(codeVerifierBytes);\n const codeChallenge = await sha256base64url(codeVerifier);\n\n const stateValue = base64url(\n new TextEncoder().encode(\n JSON.stringify({\n return_path: returnPath,\n sid: sessionIdHash,\n })\n )\n );\n\n const clientId = hubspotConnectEnv.isCimdEnabled\n ? buildCimdClientIdUrlFromRequest({\n requestUrl: c.req.url,\n basePath: options.basePath,\n xForwardedProto,\n xForwardedHost,\n requestHostHeader,\n })\n : hubspotConnectEnv.hubspotClientId;\n\n const redirectUri = buildFrontendOAuthRedirectUri(appOrigin);\n\n const authorizeUrl = new URL(hubspotConnectEnv.hubspotAuthorizationEndpoint);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('client_id', clientId);\n authorizeUrl.searchParams.set('redirect_uri', redirectUri);\n authorizeUrl.searchParams.set('code_challenge', codeChallenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n authorizeUrl.searchParams.set('state', stateValue);\n authorizeUrl.searchParams.set('sid', sessionIdHash);\n\n if (!hubspotConnectEnv.isCimdEnabled) {\n const scopesResult =\n deriveHubSpotAuthorizeScopesFromClientMetadata(cimdClientMetadata);\n if (!scopesResult.ok) {\n return c.text(scopesResult.message, scopesResult.status as 500 | 502);\n }\n authorizeUrl.searchParams.set('scope', scopesResult.scope);\n if (scopesResult.optionalScope !== undefined) {\n authorizeUrl.searchParams.set(\n 'optional_scope',\n scopesResult.optionalScope\n );\n }\n }\n\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n value: appOrigin,\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: SESSION_MAX_AGE_SEC,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_APP_SID_COOKIE_NAME,\n value: sessionId,\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: SESSION_MAX_AGE_SEC,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: TEMP_COOKIE_PKCE_VERIFIER,\n value: encodeURIComponent(codeVerifier),\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: OAUTH_TEMP_MAX_AGE_SEC,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: TEMP_COOKIE_OAUTH_STATE,\n value: encodeURIComponent(stateValue),\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: OAUTH_TEMP_MAX_AGE_SEC,\n }),\n });\n\n return c.json({ authorization_url: authorizeUrl.toString() });\n}\n","import type { Context } from 'hono';\n\nimport type { Logger } from '../../../shared/logger.ts';\nimport {\n HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n HUBSPOT_APP_SID_COOKIE_NAME,\n HUBSPOT_REFRESH_COOKIE_PREFIX,\n} from '../../constants.ts';\nimport { parseCookies } from '../../utils/cookie-utils.ts';\nimport { serializeCookie, setResponseCookie } from '../utils/cookie-utils.ts';\nimport { buildClientAssertion } from './oauth-client.ts';\nimport type { HubSpotConnectOAuthRouteOptions } from './types.ts';\nimport { buildCimdClientIdUrlFromRequest } from './utils.ts';\n\nasync function revokeToken(options: {\n revokeEndpointUrl: string;\n body: URLSearchParams;\n logger: Logger;\n}): Promise<void> {\n const { revokeEndpointUrl, body, logger } = options;\n try {\n const response = await fetch(revokeEndpointUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n });\n if (!response.ok) {\n logger.warn(\n `HubSpot token revoke returned HTTP ${response.status} ${response.statusText}`\n );\n }\n } catch (error) {\n logger.warn('HubSpot token revoke request failed', error);\n }\n}\n\nexport async function handleAuthLogout(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n) {\n const { appKeys, refreshCookiePath, basePath, hubspotConnectEnv, logger } =\n options;\n const xForwardedProto = c.req.header('x-forwarded-proto') ?? undefined;\n const xForwardedHost = c.req.header('x-forwarded-host') ?? undefined;\n const requestHostHeader = c.req.header('host') ?? undefined;\n const cookies = parseCookies(c.req.header('Cookie'));\n const accessToken = cookies[HUBSPOT_ACCESS_TOKEN_COOKIE_NAME];\n\n const clientId = hubspotConnectEnv.isCimdEnabled\n ? buildCimdClientIdUrlFromRequest({\n requestUrl: c.req.url,\n basePath,\n xForwardedProto,\n xForwardedHost,\n requestHostHeader,\n })\n : hubspotConnectEnv.hubspotClientId;\n\n const revokeEndpointUrl = new URL(\n '/oauth/v1/revoke',\n hubspotConnectEnv.hubspotOAuthApiOrigin\n ).href;\n\n if (accessToken) {\n if (hubspotConnectEnv.isCimdEnabled) {\n if (!appKeys) {\n return c.json(\n {\n error:\n 'Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD is enabled',\n },\n 500\n );\n }\n const clientAssertion = await buildClientAssertion({\n appKeys,\n clientId,\n audience: revokeEndpointUrl,\n });\n await revokeToken({\n revokeEndpointUrl,\n body: new URLSearchParams({\n token: accessToken,\n token_type_hint: 'access_token',\n client_id: clientId,\n client_assertion_type:\n 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',\n client_assertion: clientAssertion,\n }),\n logger,\n });\n } else {\n await revokeToken({\n revokeEndpointUrl,\n body: new URLSearchParams({\n token: accessToken,\n token_type_hint: 'access_token',\n client_id: clientId,\n client_secret: hubspotConnectEnv.hubspotClientSecret,\n }),\n logger,\n });\n }\n }\n\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n value: '',\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: 0,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_APP_SID_COOKIE_NAME,\n value: '',\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: 0,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_APP_ORIGIN_COOKIE_NAME,\n value: '',\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: 0,\n }),\n });\n\n Object.keys(cookies).forEach((cookieName) => {\n if (cookieName.startsWith(HUBSPOT_REFRESH_COOKIE_PREFIX)) {\n setResponseCookie({\n c,\n value: serializeCookie({\n name: cookieName,\n value: '',\n path: refreshCookiePath,\n sameSite: 'None',\n partitioned: true,\n maxAge: 0,\n }),\n });\n }\n });\n\n return c.json({ redirect_to: '/' });\n}\n","import type { Context } from 'hono';\n\nimport {\n HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n HUBSPOT_APP_SID_COOKIE_NAME,\n HUBSPOT_REFRESH_COOKIE_PREFIX,\n} from '../../constants.ts';\nimport { parseCookies } from '../../utils/cookie-utils.ts';\nimport { sha256base64url } from '../../utils/crypto-utils.ts';\nimport { serializeCookie, setResponseCookie } from '../utils/cookie-utils.ts';\nimport { REFRESH_COOKIE_MAX_AGE_SEC } from './constants.ts';\nimport {\n buildClientAssertion,\n buildClientAssertionFormParams,\n buildClientSecretFormParams,\n buildTokenEndpointDpopProof,\n requestOAuthToken,\n} from './oauth-client.ts';\nimport type { HubSpotConnectOAuthRouteOptions } from './types.ts';\nimport {\n buildCimdClientIdUrlFromRequest,\n isPositiveFiniteNumber,\n} from './utils.ts';\n\nexport async function handleAuthRefresh(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n) {\n const { appKeys, refreshCookiePath, basePath, hubspotConnectEnv } = options;\n const xForwardedProto = c.req.header('x-forwarded-proto') ?? undefined;\n const xForwardedHost = c.req.header('x-forwarded-host') ?? undefined;\n const requestHostHeader = c.req.header('host') ?? undefined;\n const cookies = parseCookies(c.req.header('Cookie'));\n const sessionId = cookies[HUBSPOT_APP_SID_COOKIE_NAME];\n if (!sessionId) {\n return c.json({ error: 'Missing session cookie' }, 401);\n }\n\n if (hubspotConnectEnv.isAppPrivateKeyRequired && !appKeys) {\n return c.json(\n {\n error:\n 'Server misconfiguration: HUBSPOT_APP_PRIVATE_KEY is required when CIMD or DPoP is enabled',\n },\n 500\n );\n }\n\n const sidHash = await sha256base64url(sessionId);\n const refreshCookieName = `${HUBSPOT_REFRESH_COOKIE_PREFIX}${sidHash}`;\n const refreshToken = cookies[refreshCookieName];\n if (!refreshToken) {\n return c.json({ error: 'Missing refresh token' }, 401);\n }\n\n const clientId = hubspotConnectEnv.isCimdEnabled\n ? buildCimdClientIdUrlFromRequest({\n requestUrl: c.req.url,\n basePath,\n xForwardedProto,\n xForwardedHost,\n requestHostHeader,\n })\n : hubspotConnectEnv.hubspotClientId;\n\n const tokenEndpointUrl = new URL(\n '/oauth/v1/token',\n hubspotConnectEnv.hubspotOAuthApiOrigin\n ).href;\n\n let dpopProof: string | undefined;\n if (hubspotConnectEnv.isDpopEnabled) {\n dpopProof = await buildTokenEndpointDpopProof({\n appKeys: appKeys!,\n tokenEndpointUrl,\n sessionIdHash: sidHash,\n });\n }\n\n let formParams: Record<string, string>;\n if (hubspotConnectEnv.isCimdEnabled) {\n const clientAssertion = await buildClientAssertion({\n appKeys: appKeys!,\n clientId,\n audience: tokenEndpointUrl,\n });\n formParams = {\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n ...buildClientAssertionFormParams({ clientId, clientAssertion }),\n };\n } else {\n formParams = {\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n ...buildClientSecretFormParams({\n clientId,\n clientSecret: hubspotConnectEnv.hubspotClientSecret,\n }),\n };\n }\n\n const tokenResult = await requestOAuthToken({\n tokenEndpointUrl,\n isDpopEnabled: hubspotConnectEnv.isDpopEnabled,\n ...(dpopProof !== undefined ? { dpopProof } : {}),\n formParams,\n });\n if (!tokenResult.ok) {\n return c.json(\n { error: `Token refresh failed: ${tokenResult.errorText}` },\n 502\n );\n }\n\n const {\n access_token: newAccessToken,\n refresh_token: newRefreshToken,\n expires_in,\n } = tokenResult.body;\n\n if (!newRefreshToken) {\n return c.json({ error: 'Token response missing refresh_token' }, 502);\n }\n if (!isPositiveFiniteNumber(expires_in)) {\n return c.json(\n { error: 'Token response missing or invalid expires_in' },\n 502\n );\n }\n\n setResponseCookie({\n c,\n value: serializeCookie({\n name: HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,\n value: newAccessToken,\n path: '/',\n sameSite: 'None',\n partitioned: true,\n maxAge: expires_in,\n }),\n });\n setResponseCookie({\n c,\n value: serializeCookie({\n name: refreshCookieName,\n value: newRefreshToken,\n path: refreshCookiePath,\n sameSite: 'None',\n partitioned: true,\n maxAge: REFRESH_COOKIE_MAX_AGE_SEC,\n }),\n });\n\n // Cookies prefixed with HUBSPOT_REFRESH_COOKIE_PREFIX that don't match the\n // new refresh cookie name are stale and need to be cleared.\n Object.keys(cookies).forEach((cookieName) => {\n if (\n cookieName.startsWith(HUBSPOT_REFRESH_COOKIE_PREFIX) &&\n cookieName !== refreshCookieName\n ) {\n setResponseCookie({\n c,\n value: serializeCookie({\n name: cookieName,\n value: '',\n path: refreshCookiePath,\n sameSite: 'None',\n partitioned: true,\n maxAge: 0,\n }),\n });\n }\n });\n\n return c.json({ expires_in });\n}\n","import type { Context } from 'hono';\n\nimport type { JwkSet } from '../../types.ts';\nimport { getJwkThumbprint } from '../../utils/jwk-utils.ts';\nimport type { HubSpotConnectCimdClientDocument } from './cimd-client-metadata-types.ts';\nimport type { HubSpotConnectOAuthRouteOptions } from './types.ts';\nimport {\n buildHubSpotAppJwksUrlFromRequest,\n buildOAuthRedirectUriFromRequest,\n type BuildOAuthRedirectUriFromRequestOptions,\n} from './utils.ts';\n\nexport async function handleCimdClientJson(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n): Promise<Response> {\n const { cimdClientMetadata, basePath } = options;\n if (!cimdClientMetadata) {\n return c.text('CIMD client metadata is not configured', 500);\n }\n\n const xForwardedProto = c.req.header('x-forwarded-proto') ?? undefined;\n const xForwardedHost = c.req.header('x-forwarded-host') ?? undefined;\n const requestHostHeader = c.req.header('host') ?? undefined;\n\n const forwarded: BuildOAuthRedirectUriFromRequestOptions = {\n requestUrl: c.req.url,\n basePath,\n xForwardedProto,\n xForwardedHost,\n requestHostHeader,\n };\n\n const body: HubSpotConnectCimdClientDocument = {\n redirect_uri: buildOAuthRedirectUriFromRequest(forwarded),\n jwks_uri: buildHubSpotAppJwksUrlFromRequest(forwarded),\n scope: cimdClientMetadata.scope,\n };\n\n return c.text(JSON.stringify(body, null, 2), 200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n}\n\nexport async function handleCimdAppJwks(\n c: Context,\n options: HubSpotConnectOAuthRouteOptions\n): Promise<Response> {\n const { appKeys, hubspotConnectEnv } = options;\n if (!hubspotConnectEnv.isCimdEnabled) {\n return c.text('Not found', 404);\n }\n if (!appKeys) {\n return c.text('Missing app keys', 503);\n }\n\n const kid = await getJwkThumbprint({\n publicKeyJwk: appKeys.appPublicKeyJwk,\n });\n\n const jwk = {\n ...appKeys.appPublicKeyJwk,\n kid,\n use: 'sig',\n alg: 'ES256',\n key_ops: ['verify'],\n ext: true,\n } as JsonWebKey;\n\n const jwks: JwkSet = { keys: [jwk] };\n return c.json(jwks);\n}\n","import type { Hono } from 'hono';\n\nimport { noopLogger, type Logger } from '../../../shared/logger.ts';\nimport type { AppKeys } from '../../types.ts';\nimport { corsMiddleware } from '../utils/cors-middleware.ts';\nimport { handleAuthComplete } from './auth-complete.ts';\nimport { handleAuthInitSession } from './auth-init-session.ts';\nimport { handleAuthLogout } from './auth-logout.ts';\nimport { handleAuthRefresh } from './auth-refresh.ts';\nimport { assertHubSpotConnectCimdClientMetadata } from './cimd-client-metadata-types.ts';\nimport type { HubSpotConnectCimdClientMetadata } from './cimd-client-metadata-types.ts';\nimport {\n handleCimdAppJwks,\n handleCimdClientJson,\n} from './cimd-public-routes.ts';\nimport type { HubSpotConnectRoutesEnv } from './load-hubspot-connect-routes-env.ts';\n\n/**\n * Options accepted by {@link registerHubSpotConnectRoutes}.\n */\nexport interface RegisterHubSpotConnectRoutesOptions {\n /** The Hono app to mount the OAuth routes on. */\n app: Hono;\n /**\n * Imported app keys from `secureStart`, or `null` when CIMD and DPoP\n * are both disabled.\n */\n appKeys: AppKeys | null;\n /**\n * Path the routes are mounted under (no trailing slash). Used to\n * scope refresh-token cookies via `Path=${basePath}/auth`.\n */\n basePath: string;\n /**\n * OAuth and client-mode settings, typically from\n * {@link loadHubSpotConnectRoutesEnv}.\n */\n hubspotConnectEnv: HubSpotConnectRoutesEnv;\n /**\n * Scope configuration for `GET /client.json` and for authorize URL\n * scopes when CIMD is off. Always required.\n */\n cimdClientMetadata: HubSpotConnectCimdClientMetadata;\n /**\n * Optional logger. When omitted the SDK uses a no-op logger so\n * server-side state never leaks into the host application's\n * console.\n */\n logger?: Logger;\n}\n\n/**\n * Mounts hubspot-connect routes: OAuth (`/auth/...`); `GET /client.json`\n * from `cimdClientMetadata`; `GET /jwks.json` when CIMD is enabled.\n */\nexport function registerHubSpotConnectRoutes(\n options: RegisterHubSpotConnectRoutesOptions\n): void {\n const {\n app,\n appKeys,\n basePath,\n hubspotConnectEnv,\n cimdClientMetadata,\n logger = noopLogger,\n } = options;\n\n if (!cimdClientMetadata) {\n throw new Error(\n 'registerHubSpotConnectRoutes: cimdClientMetadata is required'\n );\n }\n assertHubSpotConnectCimdClientMetadata(cimdClientMetadata);\n\n const refreshCookiePath = `${basePath}/auth`;\n const oauthRouteOptions = {\n appKeys,\n refreshCookiePath,\n logger,\n basePath,\n hubspotConnectEnv,\n cimdClientMetadata,\n };\n\n // Credentialed CORS for the cross-origin Lovable / Supabase shape.\n // Echoes the request `Origin` (or the pinned `__Host-hs_app_origin`\n // cookie value once init-session has run) and short-circuits OPTIONS\n // preflights with a 204 before any route handler runs.\n app.use('*', corsMiddleware());\n\n app.get('/client.json', (c) => handleCimdClientJson(c, oauthRouteOptions));\n if (hubspotConnectEnv.isCimdEnabled) {\n app.get('/jwks.json', (c) => handleCimdAppJwks(c, oauthRouteOptions));\n }\n\n app.get('/auth/init-session', (c) =>\n handleAuthInitSession(c, oauthRouteOptions)\n );\n app.post('/auth/complete', (c) => handleAuthComplete(c, oauthRouteOptions));\n app.post('/auth/refresh', (c) => handleAuthRefresh(c, oauthRouteOptions));\n app.post('/auth/logout', (c) => handleAuthLogout(c, oauthRouteOptions));\n}\n","import {\n isHubspotCimdEnabled,\n isHubspotDpopEnabled,\n requireEnv,\n} from '../../utils/env-utils.ts';\n\n/**\n * HubSpot OAuth and client-mode settings read once for hubspot-connect\n * routes. Built by {@link loadHubSpotConnectRoutesEnv}.\n */\nexport type HubSpotConnectRoutesEnv =\n | HubSpotConnectRoutesEnvCimd\n | HubSpotConnectRoutesEnvClientSecret;\n\nexport interface HubSpotConnectRoutesEnvCimd {\n hubspotAuthorizationEndpoint: string;\n hubspotOAuthApiOrigin: string;\n isCimdEnabled: true;\n isDpopEnabled: boolean;\n isAppPrivateKeyRequired: boolean;\n}\n\nexport interface HubSpotConnectRoutesEnvClientSecret {\n hubspotAuthorizationEndpoint: string;\n hubspotOAuthApiOrigin: string;\n isCimdEnabled: false;\n isDpopEnabled: boolean;\n isAppPrivateKeyRequired: boolean;\n hubspotClientId: string;\n hubspotClientSecret: string;\n}\n\n/**\n * Reads hubspot-connect environment variables from `process.env` or\n * `Deno.env` and returns a typed object for\n * {@link registerHubSpotConnectRoutes}.\n */\nexport function loadHubSpotConnectRoutesEnv(): HubSpotConnectRoutesEnv {\n const hubspotAuthorizationEndpoint = requireEnv(\n 'HUBSPOT_AUTHORIZATION_ENDPOINT'\n );\n const hubspotOAuthApiOrigin = new URL(requireEnv('HUBSPOT_OAUTH_API_ORIGIN'))\n .origin;\n const isCimdEnabled = isHubspotCimdEnabled();\n const isDpopEnabled = isHubspotDpopEnabled();\n const isAppPrivateKeyRequired = isCimdEnabled || isDpopEnabled;\n\n if (isCimdEnabled) {\n return {\n hubspotAuthorizationEndpoint,\n hubspotOAuthApiOrigin,\n isCimdEnabled: true,\n isDpopEnabled,\n isAppPrivateKeyRequired,\n };\n }\n\n return {\n hubspotAuthorizationEndpoint,\n hubspotOAuthApiOrigin,\n isCimdEnabled: false,\n isDpopEnabled,\n isAppPrivateKeyRequired,\n hubspotClientId: requireEnv('HUBSPOT_CLIENT_ID'),\n hubspotClientSecret: requireEnv('HUBSPOT_CLIENT_SECRET'),\n };\n}\n","import { Hono } from 'hono';\n\nimport type { SecureStartContext } from '../../deno/start.ts';\nimport type { HubSpotConnectCimdClientMetadata } from '../../hono/hubspot-connect-routes/cimd-client-metadata-types.ts';\nimport {\n loadHubSpotConnectRoutesEnv,\n registerHubSpotConnectRoutes,\n} from '../../hono/index.ts';\n\nconst PORT = Deno.env.get('PORT');\nconst serveOptions =\n typeof PORT === 'string' ? { port: parseInt(PORT, 10) } : {};\nconst HUBSPOT_CONNECT_BASE_PATH = '/functions/v1/hubspot-connect';\n\nexport interface RunHubSpotConnectLovableServerOptions extends SecureStartContext {\n cimdClientMetadata: HubSpotConnectCimdClientMetadata;\n}\n\nexport function runHubSpotConnectLovableServer(\n options: RunHubSpotConnectLovableServerOptions\n): Promise<void> {\n const { appKeys, cimdClientMetadata } = options;\n const hubspotConnectEnv = loadHubSpotConnectRoutesEnv();\n const result = Deno.serve(serveOptions, (request) => {\n const app = new Hono();\n\n registerHubSpotConnectRoutes({\n app: app.basePath(HUBSPOT_CONNECT_BASE_PATH),\n appKeys,\n basePath: HUBSPOT_CONNECT_BASE_PATH,\n hubspotConnectEnv,\n cimdClientMetadata,\n });\n\n return app.fetch(request);\n });\n\n console.log(`[hubspot-connect] Listening on ${result.addr.port}`);\n return Promise.resolve();\n}\n","import { secureStart } from '../../deno/start.ts';\nimport { assertHubSpotConnectCimdClientMetadata } from '../../hono/hubspot-connect-routes/cimd-client-metadata-types.ts';\nimport type { HubSpotConnectCimdClientMetadata } from '../../hono/hubspot-connect-routes/cimd-client-metadata-types.ts';\nimport { runHubSpotConnectLovableServer } from './run-hubspot-connect-lovable-server.ts';\n\nexport type { HubSpotConnectCimdClientMetadata } from '../../hono/hubspot-connect-routes/cimd-client-metadata-types.ts';\n\nexport interface StartHubSpotConnectFunctionOptions {\n client: HubSpotConnectCimdClientMetadata;\n}\n\n/**\n * Lovable-style entry point for the hubspot-connect Deno function.\n * Loads `HUBSPOT_APP_PRIVATE_KEY` via `secureStart`, then serves OAuth\n * and CIMD routes under `/functions/v1/hubspot-connect`.\n */\nexport async function startHubSpotConnectFunction(\n options: StartHubSpotConnectFunctionOptions\n): Promise<void> {\n assertHubSpotConnectCimdClientMetadata(options.client);\n await secureStart(async () => ({\n start: (context) =>\n runHubSpotConnectLovableServer({\n ...context,\n cimdClientMetadata: options.client,\n }),\n }));\n}\n","import type { Hono } from 'hono';\n\nimport type { Logger } from '../../shared/logger.ts';\nimport { createAppConnectRequestHandler } from '../hono/hono-request-handler.ts';\nimport type { AppConnectHonoEnv } from '../hono/types.ts';\nimport type { SecureStartContext } from '../secure-start-core.ts';\n\nconst PORT = Deno.env.get('PORT');\nconst serveOptions =\n typeof PORT === 'string' ? { port: parseInt(PORT, 10) } : {};\n\nexport type RegisterAppFunctionRoutesFunction = (\n app: Hono<AppConnectHonoEnv>\n) => void;\n\nexport interface CreateAppFunctionStartOptions {\n /** Base path the user's routes are mounted under (e.g. `/functions/v1/api`). */\n basePath: string;\n /** Attach app routes to the SDK-owned Hono instance. */\n registerRoutes: RegisterAppFunctionRoutesFunction;\n /** Optional logger forwarded to `createAppConnectRequestHandler`. */\n logger?: Logger;\n}\n\nexport type AppFunctionStart = (context: SecureStartContext) => Promise<void>;\n\n/**\n * Builds a Deno-style `start({ appKeys })` entry point that boots a\n * Hono app under `basePath`, wires the SDK's per-request HubSpot\n * proxy via `createAppConnectRequestHandler`, and serves it with\n * `Deno.serve` on `PORT`.\n */\nexport function createAppFunctionStart(\n options: CreateAppFunctionStartOptions\n): AppFunctionStart {\n const { basePath, registerRoutes, logger } = options;\n\n return ({ appKeys }) => {\n Deno.serve(\n serveOptions,\n createAppConnectRequestHandler({\n appKeys,\n ...(logger !== undefined ? { logger } : {}),\n registerRoutes: (app) => {\n registerRoutes(app.basePath(basePath));\n },\n })\n );\n\n console.log(\n `[app-function ${basePath}] Listening on http://localhost:${PORT}`\n );\n return Promise.resolve();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,eAAsB,cACpB,QACkB;CAClB,MAAM,MAAM,QAAQ,MAAM,IAAI;CAC9B,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,qCAAqC;CAGvD,MAAM,QAAQ,4BAA4B,IAAI;CAC9C,MAAM,iBAAiB,MAAM,OAAO,OAAO,UACzC,SACA,OACA;EAAE,MAAM;EAAS,YAAY;EAAS,EACtC,MACA,CAAC,OAAO,CACT;CACD,MAAM,aAAa,MAAM,OAAO,OAAO,UAAU,OAAO,eAAe;CACvE,IACE,WAAW,QAAQ,QACnB,WAAW,QAAQ,WACnB,OAAO,WAAW,MAAM,YACxB,OAAO,WAAW,MAAM,UAExB,MAAM,IAAI,MAAM,iDAAiD;CAEnE,MAAM,kBAA8B;EAClC,KAAK;EACL,KAAK;EACL,GAAG,WAAW;EACd,GAAG,WAAW;EACf;CAQD,OAAO;EAAE,eAAA,MAPmB,OAAO,OAAO,UACxC,SACA,OACA;GAAE,MAAM;GAAS,YAAY;GAAS,EACtC,OACA,CAAC,OAAO,CACT;EACuB;EAAiB;;;;;;;;;AC3C3C,SAAgB,OAAO,KAAiC;CACtD,MAAM,IAAI;CACV,MAAM,OAAO,EAAE;CACf,IAAI,MAAM,KACR,OAAO,KAAK,IAAI;CAElB,MAAM,OAAO,EAAE;CACf,IAAI,SAAS,KAAA,GACX,OAAO,KAAK,IAAI,IAAI,IAAI;;;;;;;;;;AAa5B,SAAgB,WAAW,KAAqB;CAC9C,MAAM,QAAQ,OAAO,IAAI;CACzB,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,0CAA0C,MAAM;CAElE,OAAO;;;;;;;AAQT,SAAgB,uBAAgC;CAC9C,OAAO,OAAO,uBAAuB,KAAK;;;;;;;AAQ5C,SAAgB,uBAAgC;CAC9C,OAAO,OAAO,uBAAuB,KAAK;;;;;;;AAQ5C,SAAgB,iCAA0C;CACxD,OAAO,sBAAsB,IAAI,sBAAsB;;;;ACzBzD,MAAM,sBAAsB;;;;;;;;AAS5B,eAAsB,eACpB,QACA,SACe;CACf,IAAI,UAA0B;CAC9B,IAAI,gCAAgC,EAAE;EACpC,MAAM,SAAS,QAAQ,QAAQ,oBAAoB,EAAE,MAAM;EAC3D,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,GAAG,oBAAoB,aAAa;EAEtD,UAAU,MAAM,cAAc,OAAO;EACrC,QAAQ,UAAU,oBAAoB;;CAIxC,QAAO,MADe,QAAQ,EACf,MAAM,EAAE,SAAS,CAAC,CAAC,OAAO,UAAU;EACjD,QAAQ,MAAM,MAAM;EACpB,OAAO,QAAQ,KAAK,EAAE;GACtB;;;;ACxDJ,MAAM,yBAA6C;CACjD,UAAU,QAAQ,KAAK,IAAI,IAAI,IAAI;CACnC,YAAY,QAAQ;EAClB,KAAK,IAAI,OAAO,IAAI;;CAEtB,OAAO,SAAS,KAAK,KAAK,KAAK;CAChC;;;;;;AAOD,SAAgB,YAAY,QAA0C;CACpE,OAAO,eAAe,QAAQ,uBAAuB;;;;ACAvD,SAAgB,uCACd,OACM;CACN,MAAM,WAAW,MAAM,OAAO;CAK9B,IAAI,EAHF,MAAM,QAAQ,SAAS,IACvB,SAAS,SAAS,KAClB,SAAS,OAAO,MAAM,OAAO,MAAM,YAAY,EAAE,SAAS,EAAE,GAE5D,MAAM,IAAI,MACR,iGACD;CAEH,MAAM,WAAW,MAAM,MAAM;CAC7B,IAAI,aAAa,KAAA,GACf;CAEF,IAAI,CAAC,MAAM,QAAQ,SAAS,EAC1B,MAAM,IAAI,MACR,4EACD;CAEH,IACE,SAAS,SAAS,KAClB,CAAC,SAAS,OAAO,MAAM,OAAO,MAAM,YAAY,EAAE,SAAS,EAAE,EAE7D,MAAM,IAAI,MACR,oFACD;;;;;;;;;ACPL,MAAa,aAAqB;CAChC,aAAa;CACb,YAAY;CACZ,YAAY;CACZ,aAAa;CACd;;;AC9CD,MAAM,WAAW;AAMjB,SAAS,8BACP,QACA,QACM;CACN,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;EACjD,IAAI,SAAS,MAAM;EACnB,IAAI,MAAM,QAAQ,MAAM,EACtB,KAAK,MAAM,QAAQ,OACjB,OAAO,OAAO,KAAK,OAAO,KAAe,CAAC;OAG5C,OAAO,OAAO,KAAK,OAAO,MAAM,CAAC;;;;;;;;;;;AAavC,SAAgB,qBACd,SACQ;CACR,OAAO,EACL,SAAS,KAAK;EACZ,IAAI,cAAc,OAAO,QAAQ;GAC/B,MAAM,EAAE,cAAc;GAGtB,IAAI,MAAM,GAAG,WAAW,UAAU;GAClC,IAAI,UAAU,YACZ,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,WAAW,EAC7D,MAAM,IAAI,QAAQ,IAAI,IAAI,IAAI,mBAAmB,OAAO,MAAM,CAAC,CAAC;GAKpE,IAAI,UAAU,aAAa;IACzB,MAAM,SAAS,IAAI,iBAAiB;IACpC,8BAA8B,QAAQ,UAAU,YAAY;IAC5D,MAAM,KAAK,OAAO,UAAU;IAC5B,IAAI,IAAI,OAAO,IAAI;;GAGrB,MAAM,UAAkC;IACtC,GAAI,UAAU,WAAW,EAAE;IAC3B,eAAe,UAAU,QAAQ,gBAAgB;IAClD;GAED,MAAM,OAAoB;IACxB,QAAQ,UAAU,OAAO,aAAa;IACtC;IACD;GAKD,IAAI,UAAU,gBAAgB,yBAAyB,UAAU,MAAM;IACrE,MAAM,WAAW,IAAI,UAAU;IAC/B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,UAAU,KACX,EAAE;KACD,IAAI,SAAS,MAAM;KACnB,IAAI,aAAa,MAAM,EACrB,SAAS,OAAO,KAAK,MAAM,OAAe;UAE1C,SAAS,OAAO,KAAK,OAAO,MAAM,CAAC;;IAGvC,KAAK,OAAO;UACP,IACL,UAAU,gBAAgB,qCAC1B;IACA,QAAQ,kBAAkB;IAC1B,IAAI,UAAU,MAAM;KAClB,MAAM,SAAS,IAAI,iBAAiB;KACpC,8BACE,QACA,UAAU,KACX;KACD,MAAM,UAAU,OAAO,UAAU;KACjC,IAAI,SAAS,KAAK,OAAO;;UAEtB;IACL,QAAQ,kBAAkB;IAC1B,IAAI,UAAU,MACZ,KAAK,OAAO,KAAK,UAAU,UAAU,KAAK;;GAG9C,MAAM,WAAW,MAAM,MAAM,KAAK,KAAK;GACvC,MAAM,kBAA0C,OAAO,OAAO,KAAK;GACnE,SAAS,QAAQ,SAAS,OAAO,QAAQ;IACvC,gBAAgB,OAAO;KACvB;GAEF,OAAO;IACL,QAAQ,SAAS;IACjB,YAAY,SAAS;IACrB,SAAS;IAET,UAAU,SAAS,WAAW,MAAM,KAAA,IAAY,MAAM,SAAS,MAAM;IACtE;IACD;IAEL;;;;;;;;;;AC/GH,MAAa,mCAAmC;;;;;AAMhD,MAAa,8BAA8B;;;;;;;;;;;;;;;;;;AAmB3C,MAAa,iCAAiC;;;;;;AAO9C,MAAa,gCAAgC;AAE7C,MAAM,yBAAyB,IAAI,IAAI;CACrC;CACA;CACA;CACD,CAAC;;;;;;;;AASF,SAAgB,sBAAsB,YAA6B;CACjE,OACE,uBAAuB,IAAI,WAAW,IACtC,WAAW,WAAA,cAAyC;;;;;;;;;;AAYxD,MAAa,4BAA4B;;;;;;;;AASzC,MAAa,0BAA0B;;;AClEvC,MAAM,qBAAqB,WAAW,qBAAqB;AAoB3D,MAAM,mBAAiC;CACrC,eAAe;CACf,OAAO,YAA+B;EACpC,OAAO,IAAI,SAAS,MAAM;GACxB,QAAQ;GACR,YAAY;GACZ,SAAS,EACP,gBAAgB,oBACjB;GACF,CAAC;;CAEL;AAED,MAAM,gBAAgB,EAAE;AAExB,SAAgB,mBACd,SACc;CACd,MAAM,EAAE,iBAAiB,SAAS,SAAS,eAAe;CAE1D,IAAI,sBAAsB,IAAI,YAAY,MACxC,MAAM,IAAI,MACR,iFACD;CAGH,MAAM,EAAE,aAAa,cAAc;CAEnC,IAAI,CAAC,eAAe,CAAC,WAAW;EAC9B,OAAO,MACL,wEACD;EACD,OAAO;;CAGT,eAAe,WAAW,SAAiD;EACzE,MAAM,EAAE,MAAM,SAAS,OAAO,UAAU,eAAe,SAAS;EAEhE,MAAM,YAAY,GAAG,qBAAqB;EAC1C,MAAM,UAAU,sBAAsB;EAEtC,IAAI;EACJ,IAAI,SAAS;GACX,MAAM,MAAM,MAAM,gBAAgB,YAAa;GAC/C,MAAM,MAAM,MAAM,gBAAgB,UAAW;GAC7C,MAAM,YAAY,MAAM,cAAc;IAC3B;IACT,QAAQ;KACN,KAAK;KACL,KAAK;KACL,KAAK,OAAO,YAAY;KACxB,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;KAClC;KACA;KACD;IACF,CAAC;GACF,uBAAuB;IACrB,eAAe,QAAQ;IACvB,MAAM;IACP;SAED,uBAAuB,EACrB,eAAe,UAAU,eAC1B;EAKH,MAAM,cAA2B;GAC/B,SAAS;IAHY,GAAG;IAAS,GAAG;IAGf;GACrB;GACD;EAED,IAAI,QAAQ,MACV,YAAY,OAAO;EAGrB,OAAO,MAAM,WAAW,YAAY;;CAGtC,OAAO;EACL,eAAe;EACf,OAAO;EACR;;;;;;;;;;;;AC1GH,SAAgB,aACd,cACwB;CACxB,IAAI,CAAC,cAAc,OAAO,EAAE;CAC5B,OAAO,OAAO,YACZ,aACG,MAAM,IAAI,CACV,KAAK,SAAS;EACb,MAAM,QAAQ,KAAK,QAAQ,IAAI;EAC/B,IAAI,UAAU,IAAI,OAAO,CAAC,KAAK,MAAM,EAAE,GAAG;EAC1C,OAAO,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC;GAIlE,CACD,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CACvC;;;;ACrBH,SAAS,iBAAiB,SAAsC;CAC9D,MAAM,QAAkB,EAAE;CAC1B,KAAK,MAAM,CAAC,MAAM,UAAU,SAC1B,MAAM,KAAK,GAAG,KAAK,GAAG,QAAQ;CAEhC,OAAO,MAAM,KAAK,KAAK;;;;;;;;;;;;AAazB,SAAgB,sBAAsB,SAAwB;CAC5D,MAAM,UAAU,aAAa,QAAQ,IAAI,SAAS,CAAC;CACnD,MAAM,4BAAY,IAAI,KAAqB;CAC3C,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,EACjD,IAAI,CAAC,sBAAsB,KAAK,EAC9B,UAAU,IAAI,MAAM,MAAM;CAI9B,IAAI,UAAU,SAAS,GACrB,QAAQ,OAAO,SAAS;MAExB,QAAQ,IAAI,UAAU,iBAAiB,UAAU,CAAC;;;;;;;;;;;;;AAetD,SAAgB,gBAAgB,UAA4B;CAC1D,MAAM,UAAU,IAAI,QAAQ,SAAS,QAAQ;CAC7C,sBAAsB,QAAQ;CAE9B,MAAM,OAAoB;EACxB,QAAQ,SAAS;EACjB;EACA,UAAU,SAAS;EACnB,QAAQ,SAAS;EAClB;CAED,IAAI,SAAS,SAAS,MAAM;EAC1B,KAAK,OAAO,SAAS;EACrB,KAA2C,SAAS;;CAGtD,OAAO,IAAI,QAAQ,SAAS,KAAK,KAAK;;;;;;;;;;;ACpDxC,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC,KAAK,KAAK;AAEZ,MAAM,kBAAkB;AAExB,MAAM,4BAA4B;;;;;;;;;AAUlC,SAAS,qBAAqB,GAA2B;CAEvD,MAAM,SADU,aAAa,EAAE,IAAI,OAAO,SAAS,CAC7B,CAAC;CACvB,IAAI,QAAQ,OAAO;CACnB,OAAO,EAAE,IAAI,OAAO,SAAS,IAAI;;AAGnC,SAAS,qBAAqB,GAAY,aAA2B;CACnE,EAAE,IAAI,QAAQ,IAAI,+BAA+B,YAAY;CAC7D,EAAE,IAAI,QAAQ,IAAI,oCAAoC,OAAO;CAI7D,EAAE,IAAI,QAAQ,IAAI,QAAQ,iBAAiB;;;;;;;;;;;;;;;;;;;;AAqB7C,SAAgB,iBAAoC;CAClD,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,cAAc,qBAAqB,EAAE;EAE3C,IAAI,EAAE,IAAI,WAAW,WAAW;GAC9B,MAAM,UAAU,IAAI,SAAS;GAC7B,IAAI,aAAa;IACf,QAAQ,IAAI,+BAA+B,YAAY;IACvD,QAAQ,IAAI,oCAAoC,OAAO;IACvD,QAAQ,IAAI,QAAQ,iBAAiB;;GAEvC,QAAQ,IAAI,gCAAgC,gBAAgB;GAC5D,QAAQ,IAAI,gCAAgC,gBAAgB;GAC5D,QAAQ,IAAI,0BAA0B,0BAA0B;GAChE,OAAO,IAAI,SAAS,MAAM;IAAE,QAAQ;IAAK;IAAS,CAAC;;EAGrD,MAAM,MAAM;EAEZ,IAAI,aACF,qBAAqB,GAAG,YAAY;;;;;;;;;;;;;;AC9B1C,SAAgB,+BACd,SACwB;CACxB,MAAM,EAAE,gBAAgB,SAAS,SAAS,eAAe;CACzD,MAAM,MAAM,IAAI,MAAyB;CAKzC,IAAI,IAAI,KAAK,gBAAgB,CAAC;CAS9B,IAAI,IAAI,KAAK,OAAO,GAAG,SAAS;EAC9B,MAAM,EAAE,kBAAkB,EAAE,IAAI;EAChC,IAAI,CAAC,eACH,OAAO,EAAE,KAAK,EAAE,OAAO,gBAAgB,EAAE,IAAI;EAG/C,MAAM,MAAM;GAEZ;CAEF,eAAe,IAAI;CAEnB,QAAQ,YAAqB;EAC3B,MAAM,SAAS,QAAQ,QAAQ,IAAI,SAAS;EAC5C,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,uBAAuB;EAEzC,MAAM,UAAU,aAAa,OAAO;EACpC,MAAM,cAAc,QAAQ;EAK5B,MAAM,QAAQ,mBAAmB;GAC/B,iBAAA;IAHyC;IAAa,WAFtC,QAAQ;IAKT;GACf;GACA;GACD,CAAC;EAEF,MAAM,SAAS,oBAAoB,EACjC,SAAS,CACP,qBAAqB,EACnB,sBAAsB;GACpB,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,uBAAuB;GAEzC,OAAO;KAEV,CAAC,CACH,EACF,CAAC;EAEF,MAAM,mBAAmB,gBAAgB,QAAQ;EAEjD,MAAM,eAAuC,EAC3C,SAAS;GACP;GACA;GACA,eAAe,MAAM;GACtB,EACF;EAED,OAAO,IAAI,MAAM,kBAAkB,aAAa;;;;;;;;;;;;;;;;;;;ACtGpD,MAAa,iCAAiC;;;;;AAM9C,MAAa,2BAA2B;;;;;AAMxC,MAAa,4BAA4B;;;;;;;;AC5BzC,SAAgB,kBAAkB,SAAyC;CACzE,MAAM,EAAE,GAAG,UAAU;CACrB,EAAE,OAAO,cAAc,OAAO,EAAE,QAAQ,MAAM,CAAC;;;;;;;AA8CjD,SAAgB,gBAAgB,SAAyC;CACvE,MAAM,EACJ,MACA,OACA,MACA,WAAW,UACX,QACA,SAAS,MACT,WAAW,MACX,cAAc,UACZ;CACJ,MAAM,QAAkB,CAAC,GAAG,KAAK,GAAG,QAAQ;CAC5C,IAAI,UAAU,MAAM,KAAK,WAAW;CACpC,IAAI,QAAQ,MAAM,KAAK,SAAS;CAChC,MAAM,KAAK,YAAY,WAAW;CAClC,MAAM,KAAK,QAAQ,OAAO;CAC1B,MAAM,KAAK,WAAW,SAAS;CAC/B,IAAI,aAAa,MAAM,KAAK,cAAc;CAC1C,OAAO,MAAM,KAAK,KAAK;;;;AC9EzB,MAAa,sBAAsB;AACnC,MAAa,yBAAyB;AACtC,MAAa,6BAA6B;;;;;;;;ACO1C,MAAM,2BAA2B;;;;;AAMjC,MAAM,4BACJ;;;;;AA0BF,eAAsB,qBACpB,SACiB;CACjB,MAAM,EAAE,SAAS,UAAU,aAAa;CACxC,OAAO,QAAQ;EACb,YAAY,QAAQ;EACpB,SAAS;GACP,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,OAAO,YAAY;GACzB;EACD,YAAY;EACb,CAAC;;;;;;;AAgBJ,eAAsB,4BACpB,SACiB;CACjB,MAAM,EAAE,SAAS,kBAAkB,kBAAkB;CACrD,OAAO,cAAc;EACnB;EACA,QAAQ;GACN,KAAK;GACL,KAAK;GACL,KAAK,OAAO,YAAY;GACxB,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAClC,KAAK;GACN;EACF,CAAC;;;;;;;;;AAyCJ,eAAsB,kBACpB,SACkC;CAClC,MAAM,EAAE,kBAAkB,YAAY,WAAW,kBAAkB;CACnE,MAAM,UAAkC,EACtC,gBAAgB,qCACjB;CACD,IAAI,eAAe;EACjB,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,8CAA8C;EAEhE,QAAQ,OAAO;;CAEjB,MAAM,gBAAgB,MAAM,MAAM,kBAAkB;EAClD,QAAQ;EACR;EACA,MAAM,IAAI,gBAAgB,WAAW;EACtC,CAAC;CACF,IAAI,CAAC,cAAc,IAAI;EACrB,MAAM,YAAY,MAAM,cAAc,MAAM;EAC5C,OAAO;GAAE,IAAI;GAAO,QAAQ,cAAc;GAAQ;GAAW;;CAG/D,OAAO;EAAE,IAAI;EAAM,MAAA,MADC,cAAc,MAAM;EACf;;;;;;AAO3B,SAAgB,+BAA+B,OAGpB;CACzB,MAAM,EAAE,UAAU,oBAAoB;CACtC,OAAO;EACL,WAAW;EACX,uBAAuB;EACvB,kBAAkB;EACnB;;AAQH,SAAgB,4BACd,SACwB;CACxB,MAAM,EAAE,UAAU,iBAAiB;CACnC,OAAO;EACL,WAAW;EACX,eAAe;EAChB;;;;AChLH,SAAgB,gBAAgB,MAAsB;CACpD,OAAO,gBAAgB;EACrB;EACA,OAAO;EACP,MAAM;EACN,UAAU;EACV,QAAQ;EACR,aAAa;EACd,CAAC;;;;;;;;;;;;;;;;;;;AAoBJ,SAAgB,qBACd,cACe;CACf,IAAI,CAAC,cAAc,OAAO;CAC1B,IAAI;CACJ,IAAI;EACF,SAAS,IAAI,IAAI,aAAa;SACxB;EACN,OAAO;;CAET,IAAI,OAAO,aAAa,OAAO,OAAO,aAAa,IAAI,OAAO;CAC9D,IAAI,OAAO,WAAW,MAAM,OAAO,SAAS,IAAI,OAAO;CACvD,IAAI,OAAO,aAAa,UAAU,OAAO,OAAO;CAChD,IACE,OAAO,aAAa,YACnB,OAAO,aAAa,eAAe,OAAO,aAAa,cAExD,OAAO,OAAO;CAEhB,OAAO;;;;;;;;;;;;;AAcT,SAAgB,8BAA8B,WAA2B;CACvE,OAAO,GAAG,YAAY;;AAGxB,SAAgB,iBAAiB,SAA0B;CACzD,IAAI,CAAC,QAAQ,WAAW,IAAI,EAAE,OAAO;CACrC,IAAI,QAAQ,SAAS,KAAK,EAAE,OAAO;CACnC,IAAI;CACJ,IAAI;EACF,UAAU,mBAAmB,QAAQ;SAC/B;EACN,OAAO;;CAET,IAAI,CAAC,QAAQ,WAAW,IAAI,EAAE,OAAO;CACrC,MAAM,SAAS,QAAQ,OAAO,EAAE;CAChC,IAAI,WAAW,OAAO,WAAW,MAAM,OAAO;CAC9C,OAAO;;AAkDT,SAAS,gCAAgC,UAA0B;CACjE,OAAO,SAAS,SAAS,IAAI,IAAI,SAAS,SAAS,IAC/C,SAAS,MAAM,GAAG,GAAG,GACrB;;;;;;AAON,SAAgB,iCACd,SACQ;CACR,MAAM,EAAE,YAAY,iBAAiB,gBAAgB,sBACnD;CACF,MAAM,QAAQ,iBAAiB,MAAM,IAAI,CAAC,IAAI,MAAM;CACpD,IAAI,UAAU,UAAU,UAAU,UAAU,UAAU;EACpD,MAAM,gBAAgB,gBAAgB,MAAM,IAAI,CAAC,IAAI,MAAM;EAC3D,MAAM,aAAa,mBAAmB,MAAM,IAAI,CAAC,IAAI,MAAM;EAE3D,OAAO,GAAG,MAAM,KADC,iBAAiB,cAAc,IAAI,IAAI,WAAW,CAAC;;CAGtE,OAAO,IAAI,IAAI,WAAW,CAAC;;;;;;;;AAS7B,SAAgB,iCACd,SACQ;CACR,MAAM,UAAU,gCAAgC,QAAQ,SAAS;CAEjE,OAAO,GADQ,iCAAiC,QAChC,GAAG,QAAQ;;;;;AAM7B,SAAgB,gCACd,SACQ;CACR,MAAM,UAAU,gCAAgC,QAAQ,SAAS;CAEjE,OAAO,GADQ,iCAAiC,QAChC,GAAG,QAAQ;;;;;AAM7B,SAAgB,kCACd,SACQ;CACR,MAAM,UAAU,gCAAgC,QAAQ,SAAS;CAEjE,OAAO,GADQ,iCAAiC,QAChC,GAAG,QAAQ;;AAG7B,SAAgB,uBAAuB,OAAiC;CACtE,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,IAAI,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/HxE,eAAsB,mBACpB,GACA,SACA;CACA,MAAM,EAAE,SAAS,mBAAmB,sBAAsB;CAC1D,MAAM,kBAAkB,EAAE,IAAI,OAAO,oBAAoB,IAAI,KAAA;CAC7D,MAAM,iBAAiB,EAAE,IAAI,OAAO,mBAAmB,IAAI,KAAA;CAC3D,MAAM,oBAAoB,EAAE,IAAI,OAAO,OAAO,IAAI,KAAA;CAClD,MAAM,OAAO,EAAE,IAAI,MAAM,yBAAyB;CAClD,MAAM,QAAQ,EAAE,IAAI,MAAM,0BAA0B;CAEpD,IAAI,CAAC,QAAQ,CAAC,OACZ,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,EAAE,IAAI;CAGxD,IAAI,kBAAkB,2BAA2B,CAAC,SAChD,OAAO,EAAE,KACP,EACE,OACE,6FACH,EACD,IACD;CAGH,MAAM,UAAU,aAAa,EAAE,IAAI,OAAO,SAAS,CAAC;CACpD,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,eAAe,QAAQ;CAC7B,MAAM,kBAAkB,QAAQ;CAEhC,IAAI,CAAC,iBAAiB,UAAU,mBAAmB,cAAc,EAC/D,OAAO,EAAE,KAAK,EAAE,OAAO,kBAAkB,EAAE,IAAI;CAEjD,IAAI,CAAC,cACH,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,EAAE,IAAI;CAMxD,MAAM,YAAY,qBAAqB,gBAAgB;CACvD,IAAI,CAAC,WACH,OAAO,EAAE,KAAK,EAAE,OAAO,6BAA6B,EAAE,IAAI;CAG5D,IAAI;CACJ,IAAI;EACF,eAAe,KAAK,MAClB,IAAI,aAAa,CAAC,OAAO,gBAAgB,mBAAmB,MAAM,CAAC,CAAC,CACrE;SACK;EACN,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,EAAE,IAAI;;CAExD,MAAM,aAAa,aAAa;CAChC,IAAI,CAAC,cAAc,CAAC,iBAAiB,WAAW,EAC9C,OAAO,EAAE,KAAK,EAAE,OAAO,gCAAgC,EAAE,IAAI;CAG/D,MAAM,YAAY,aAAa;CAC/B,IAAI,CAAC,WACH,OAAO,EAAE,KAAK,EAAE,OAAO,8BAA8B,EAAE,IAAI;CAG7D,MAAM,sBAAsB,mBAAmB,aAAa;CAE5D,MAAM,WAAW,kBAAkB,gBAC/B,gCAAgC;EAC9B,YAAY,EAAE,IAAI;EAClB,UAAU,QAAQ;EAClB;EACA;EACA;EACD,CAAC,GACF,kBAAkB;CAEtB,MAAM,cAAc,8BAA8B,UAAU;CAE5D,MAAM,mBAAmB,IAAI,IAC3B,mBACA,kBAAkB,sBACnB,CAAC;CAEF,IAAI;CACJ,IAAI,kBAAkB,eACpB,YAAY,MAAM,4BAA4B;EACnC;EACT;EACA,eAAe;EAChB,CAAC;CAGJ,IAAI;CACJ,IAAI,kBAAkB,eAMpB,aAAa;EACX,YAAY;EACZ;EACA,eAAe;EACf,cAAc;EACd,GAAG,+BAA+B;GAAE;GAAU,iBAAA,MAVlB,qBAAqB;IACxC;IACT;IACA,UAAU;IACX,CAAC;GAM+D,CAAC;EACjE;MAED,aAAa;EACX,YAAY;EACZ;EACA,eAAe;EACf,cAAc;EACd,GAAG,4BAA4B;GAC7B;GACA,cAAc,kBAAkB;GACjC,CAAC;EACH;CAGH,MAAM,cAAc,MAAM,kBAAkB;EAC1C;EACA,eAAe,kBAAkB;EACjC,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;EAChD;EACD,CAAC;CACF,IAAI,CAAC,YAAY,IACf,OAAO,EAAE,KACP,EAAE,OAAO,0BAA0B,YAAY,aAAa,EAC5D,IACD;CAGH,MAAM,EACJ,cAAc,aACd,eAAe,cACf,eACE,YAAY;CAChB,IAAI,CAAC,cACH,OAAO,EAAE,KAAK,EAAE,OAAO,wCAAwC,EAAE,IAAI;CAEvE,IAAI,CAAC,uBAAuB,WAAW,EACrC,OAAO,EAAE,KACP,EAAE,OAAO,gDAAgD,EACzD,IACD;CAGH,MAAM,YAAY,KAAK,KAAK,GAAG,aAAa;CAC5C,MAAM,oBAAoB,GAAG,gCAAgC;CAE7D,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAAE;EAAG,OAAO,gBAAgB,0BAA0B;EAAE,CAAC;CAC3E,kBAAkB;EAAE;EAAG,OAAO,gBAAgB,wBAAwB;EAAE,CAAC;CAEzE,OAAO,EAAE,KAAK;EAAE,YAAY;EAAW,aAAa;EAAY,CAAC;;;;;;;;;ACxNnE,SAAgB,+CACd,UACsD;CACtD,MAAM,WAAW,SAAS,OAAO;CAMjC,IAAI,EAJF,MAAM,QAAQ,SAAS,IACvB,SAAS,SAAS,KAClB,SAAS,OAAO,MAAM,OAAO,MAAM,YAAY,EAAE,SAAS,EAAE,GAG5D,OAAO;EACL,IAAI;EACJ,QAAQ;EACR,SAAS;EACV;CAGH,MAAM,QAAQ,SAAS,KAAK,IAAI;CAEhC,MAAM,cAAc,SAAS,MAAM;CACnC,IAAI,eAAe,MACjB,OAAO;EAAE,IAAI;EAAM;EAAO;CAG5B,IAAI,CAAC,MAAM,QAAQ,YAAY,EAC7B,OAAO;EACL,IAAI;EACJ,QAAQ;EACR,SAAS;EACV;CAGH,IAAI,YAAY,WAAW,GACzB,OAAO;EAAE,IAAI;EAAM;EAAO;CAG5B,IAAI,CAAC,YAAY,OAAO,MAAM,OAAO,MAAM,YAAY,EAAE,SAAS,EAAE,EAClE,OAAO;EACL,IAAI;EACJ,QAAQ;EACR,SAAS;EACV;CAGH,OAAO;EACL,IAAI;EACJ;EACA,eAAe,YAAY,KAAK,IAAI;EACrC;;;;AClDH,eAAsB,sBACpB,GACA,SACA;CACA,MAAM,EAAE,mBAAmB,uBAAuB;CAClD,MAAM,kBAAkB,EAAE,IAAI,OAAO,oBAAoB,IAAI,KAAA;CAC7D,MAAM,iBAAiB,EAAE,IAAI,OAAO,mBAAmB,IAAI,KAAA;CAC3D,MAAM,oBAAoB,EAAE,IAAI,OAAO,OAAO,IAAI,KAAA;CAElD,MAAM,aAAa,IADH,IAAI,EAAE,IAAI,IACJ,CAAC,aAAa,IAAI,cAAc,IAAI;CAC1D,IAAI,CAAC,iBAAiB,WAAW,EAC/B,OAAO,EAAE,KAAK,uBAAuB,IAAI;CAO3C,MAAM,YAAY,qBAAqB,EAAE,IAAI,OAAO,SAAS,CAAC;CAC9D,IAAI,CAAC,WACH,OAAO,EAAE,KACP,gFACA,IACD;CAGH,MAAM,iBAAiB,IAAI,WAAW,GAAG;CACzC,OAAO,gBAAgB,eAAe;CACtC,MAAM,YAAY,UAAU,eAAe;CAC3C,MAAM,gBAAgB,MAAM,gBAAgB,UAAU;CAEtD,MAAM,oBAAoB,IAAI,WAAW,GAAG;CAC5C,OAAO,gBAAgB,kBAAkB;CACzC,MAAM,eAAe,UAAU,kBAAkB;CACjD,MAAM,gBAAgB,MAAM,gBAAgB,aAAa;CAEzD,MAAM,aAAa,UACjB,IAAI,aAAa,CAAC,OAChB,KAAK,UAAU;EACb,aAAa;EACb,KAAK;EACN,CAAC,CACH,CACF;CAED,MAAM,WAAW,kBAAkB,gBAC/B,gCAAgC;EAC9B,YAAY,EAAE,IAAI;EAClB,UAAU,QAAQ;EAClB;EACA;EACA;EACD,CAAC,GACF,kBAAkB;CAEtB,MAAM,cAAc,8BAA8B,UAAU;CAE5D,MAAM,eAAe,IAAI,IAAI,kBAAkB,6BAA6B;CAC5E,aAAa,aAAa,IAAI,iBAAiB,OAAO;CACtD,aAAa,aAAa,IAAI,aAAa,SAAS;CACpD,aAAa,aAAa,IAAI,gBAAgB,YAAY;CAC1D,aAAa,aAAa,IAAI,kBAAkB,cAAc;CAC9D,aAAa,aAAa,IAAI,yBAAyB,OAAO;CAC9D,aAAa,aAAa,IAAI,SAAS,WAAW;CAClD,aAAa,aAAa,IAAI,OAAO,cAAc;CAEnD,IAAI,CAAC,kBAAkB,eAAe;EACpC,MAAM,eACJ,+CAA+C,mBAAmB;EACpE,IAAI,CAAC,aAAa,IAChB,OAAO,EAAE,KAAK,aAAa,SAAS,aAAa,OAAoB;EAEvE,aAAa,aAAa,IAAI,SAAS,aAAa,MAAM;EAC1D,IAAI,aAAa,kBAAkB,KAAA,GACjC,aAAa,aAAa,IACxB,kBACA,aAAa,cACd;;CAIL,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO,mBAAmB,aAAa;GACvC,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO,mBAAmB,WAAW;GACrC,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CAEF,OAAO,EAAE,KAAK,EAAE,mBAAmB,aAAa,UAAU,EAAE,CAAC;;;;ACpI/D,eAAe,YAAY,SAIT;CAChB,MAAM,EAAE,mBAAmB,MAAM,WAAW;CAC5C,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,mBAAmB;GAC9C,QAAQ;GACR,SAAS,EAAE,gBAAgB,qCAAqC;GAChE;GACD,CAAC;EACF,IAAI,CAAC,SAAS,IACZ,OAAO,KACL,sCAAsC,SAAS,OAAO,GAAG,SAAS,aACnE;UAEI,OAAO;EACd,OAAO,KAAK,uCAAuC,MAAM;;;AAI7D,eAAsB,iBACpB,GACA,SACA;CACA,MAAM,EAAE,SAAS,mBAAmB,UAAU,mBAAmB,WAC/D;CACF,MAAM,kBAAkB,EAAE,IAAI,OAAO,oBAAoB,IAAI,KAAA;CAC7D,MAAM,iBAAiB,EAAE,IAAI,OAAO,mBAAmB,IAAI,KAAA;CAC3D,MAAM,oBAAoB,EAAE,IAAI,OAAO,OAAO,IAAI,KAAA;CAClD,MAAM,UAAU,aAAa,EAAE,IAAI,OAAO,SAAS,CAAC;CACpD,MAAM,cAAc,QAAQ;CAE5B,MAAM,WAAW,kBAAkB,gBAC/B,gCAAgC;EAC9B,YAAY,EAAE,IAAI;EAClB;EACA;EACA;EACA;EACD,CAAC,GACF,kBAAkB;CAEtB,MAAM,oBAAoB,IAAI,IAC5B,oBACA,kBAAkB,sBACnB,CAAC;CAEF,IAAI,aACF,IAAI,kBAAkB,eAAe;EACnC,IAAI,CAAC,SACH,OAAO,EAAE,KACP,EACE,OACE,qFACH,EACD,IACD;EAEH,MAAM,kBAAkB,MAAM,qBAAqB;GACjD;GACA;GACA,UAAU;GACX,CAAC;EACF,MAAM,YAAY;GAChB;GACA,MAAM,IAAI,gBAAgB;IACxB,OAAO;IACP,iBAAiB;IACjB,WAAW;IACX,uBACE;IACF,kBAAkB;IACnB,CAAC;GACF;GACD,CAAC;QAEF,MAAM,YAAY;EAChB;EACA,MAAM,IAAI,gBAAgB;GACxB,OAAO;GACP,iBAAiB;GACjB,WAAW;GACX,eAAe,kBAAkB;GAClC,CAAC;EACF;EACD,CAAC;CAIN,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CAEF,OAAO,KAAK,QAAQ,CAAC,SAAS,eAAe;EAC3C,IAAI,WAAW,WAAA,cAAyC,EACtD,kBAAkB;GAChB;GACA,OAAO,gBAAgB;IACrB,MAAM;IACN,OAAO;IACP,MAAM;IACN,UAAU;IACV,aAAa;IACb,QAAQ;IACT,CAAC;GACH,CAAC;GAEJ;CAEF,OAAO,EAAE,KAAK,EAAE,aAAa,KAAK,CAAC;;;;ACpIrC,eAAsB,kBACpB,GACA,SACA;CACA,MAAM,EAAE,SAAS,mBAAmB,UAAU,sBAAsB;CACpE,MAAM,kBAAkB,EAAE,IAAI,OAAO,oBAAoB,IAAI,KAAA;CAC7D,MAAM,iBAAiB,EAAE,IAAI,OAAO,mBAAmB,IAAI,KAAA;CAC3D,MAAM,oBAAoB,EAAE,IAAI,OAAO,OAAO,IAAI,KAAA;CAClD,MAAM,UAAU,aAAa,EAAE,IAAI,OAAO,SAAS,CAAC;CACpD,MAAM,YAAY,QAAQ;CAC1B,IAAI,CAAC,WACH,OAAO,EAAE,KAAK,EAAE,OAAO,0BAA0B,EAAE,IAAI;CAGzD,IAAI,kBAAkB,2BAA2B,CAAC,SAChD,OAAO,EAAE,KACP,EACE,OACE,6FACH,EACD,IACD;CAGH,MAAM,UAAU,MAAM,gBAAgB,UAAU;CAChD,MAAM,oBAAoB,GAAG,gCAAgC;CAC7D,MAAM,eAAe,QAAQ;CAC7B,IAAI,CAAC,cACH,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,EAAE,IAAI;CAGxD,MAAM,WAAW,kBAAkB,gBAC/B,gCAAgC;EAC9B,YAAY,EAAE,IAAI;EAClB;EACA;EACA;EACA;EACD,CAAC,GACF,kBAAkB;CAEtB,MAAM,mBAAmB,IAAI,IAC3B,mBACA,kBAAkB,sBACnB,CAAC;CAEF,IAAI;CACJ,IAAI,kBAAkB,eACpB,YAAY,MAAM,4BAA4B;EACnC;EACT;EACA,eAAe;EAChB,CAAC;CAGJ,IAAI;CACJ,IAAI,kBAAkB,eAMpB,aAAa;EACX,YAAY;EACZ,eAAe;EACf,GAAG,+BAA+B;GAAE;GAAU,iBAAA,MARlB,qBAAqB;IACxC;IACT;IACA,UAAU;IACX,CAAC;GAI+D,CAAC;EACjE;MAED,aAAa;EACX,YAAY;EACZ,eAAe;EACf,GAAG,4BAA4B;GAC7B;GACA,cAAc,kBAAkB;GACjC,CAAC;EACH;CAGH,MAAM,cAAc,MAAM,kBAAkB;EAC1C;EACA,eAAe,kBAAkB;EACjC,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;EAChD;EACD,CAAC;CACF,IAAI,CAAC,YAAY,IACf,OAAO,EAAE,KACP,EAAE,OAAO,yBAAyB,YAAY,aAAa,EAC3D,IACD;CAGH,MAAM,EACJ,cAAc,gBACd,eAAe,iBACf,eACE,YAAY;CAEhB,IAAI,CAAC,iBACH,OAAO,EAAE,KAAK,EAAE,OAAO,wCAAwC,EAAE,IAAI;CAEvE,IAAI,CAAC,uBAAuB,WAAW,EACrC,OAAO,EAAE,KACP,EAAE,OAAO,gDAAgD,EACzD,IACD;CAGH,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CACF,kBAAkB;EAChB;EACA,OAAO,gBAAgB;GACrB,MAAM;GACN,OAAO;GACP,MAAM;GACN,UAAU;GACV,aAAa;GACb,QAAQ;GACT,CAAC;EACH,CAAC;CAIF,OAAO,KAAK,QAAQ,CAAC,SAAS,eAAe;EAC3C,IACE,WAAW,WAAA,cAAyC,IACpD,eAAe,mBAEf,kBAAkB;GAChB;GACA,OAAO,gBAAgB;IACrB,MAAM;IACN,OAAO;IACP,MAAM;IACN,UAAU;IACV,aAAa;IACb,QAAQ;IACT,CAAC;GACH,CAAC;GAEJ;CAEF,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC;;;;ACnK/B,eAAsB,qBACpB,GACA,SACmB;CACnB,MAAM,EAAE,oBAAoB,aAAa;CACzC,IAAI,CAAC,oBACH,OAAO,EAAE,KAAK,0CAA0C,IAAI;CAG9D,MAAM,kBAAkB,EAAE,IAAI,OAAO,oBAAoB,IAAI,KAAA;CAC7D,MAAM,iBAAiB,EAAE,IAAI,OAAO,mBAAmB,IAAI,KAAA;CAC3D,MAAM,oBAAoB,EAAE,IAAI,OAAO,OAAO,IAAI,KAAA;CAElD,MAAM,YAAqD;EACzD,YAAY,EAAE,IAAI;EAClB;EACA;EACA;EACA;EACD;CAED,MAAM,OAAyC;EAC7C,cAAc,iCAAiC,UAAU;EACzD,UAAU,kCAAkC,UAAU;EACtD,OAAO,mBAAmB;EAC3B;CAED,OAAO,EAAE,KAAK,KAAK,UAAU,MAAM,MAAM,EAAE,EAAE,KAAK,EAChD,gBAAgB,mCACjB,CAAC;;AAGJ,eAAsB,kBACpB,GACA,SACmB;CACnB,MAAM,EAAE,SAAS,sBAAsB;CACvC,IAAI,CAAC,kBAAkB,eACrB,OAAO,EAAE,KAAK,aAAa,IAAI;CAEjC,IAAI,CAAC,SACH,OAAO,EAAE,KAAK,oBAAoB,IAAI;CAGxC,MAAM,MAAM,MAAM,iBAAiB,EACjC,cAAc,QAAQ,iBACvB,CAAC;CAWF,MAAM,OAAe,EAAE,MAAM,CAAC;EAR5B,GAAG,QAAQ;EACX;EACA,KAAK;EACL,KAAK;EACL,SAAS,CAAC,SAAS;EACnB,KAAK;EAG0B,CAAC,EAAE;CACpC,OAAO,EAAE,KAAK,KAAK;;;;;;;;ACfrB,SAAgB,6BACd,SACM;CACN,MAAM,EACJ,KACA,SACA,UACA,mBACA,oBACA,SAAS,eACP;CAEJ,IAAI,CAAC,oBACH,MAAM,IAAI,MACR,+DACD;CAEH,uCAAuC,mBAAmB;CAG1D,MAAM,oBAAoB;EACxB;EACA,mBAAA,GAH2B,SAAS;EAIpC;EACA;EACA;EACA;EACD;CAMD,IAAI,IAAI,KAAK,gBAAgB,CAAC;CAE9B,IAAI,IAAI,iBAAiB,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;CAC1E,IAAI,kBAAkB,eACpB,IAAI,IAAI,eAAe,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;CAGvE,IAAI,IAAI,uBAAuB,MAC7B,sBAAsB,GAAG,kBAAkB,CAC5C;CACD,IAAI,KAAK,mBAAmB,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;CAC3E,IAAI,KAAK,kBAAkB,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;CACzE,IAAI,KAAK,iBAAiB,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;;;;;;;;;AC/DzE,SAAgB,8BAAuD;CACrE,MAAM,+BAA+B,WACnC,iCACD;CACD,MAAM,wBAAwB,IAAI,IAAI,WAAW,2BAA2B,CAAC,CAC1E;CACH,MAAM,gBAAgB,sBAAsB;CAC5C,MAAM,gBAAgB,sBAAsB;CAC5C,MAAM,0BAA0B,iBAAiB;CAEjD,IAAI,eACF,OAAO;EACL;EACA;EACA,eAAe;EACf;EACA;EACD;CAGH,OAAO;EACL;EACA;EACA,eAAe;EACf;EACA;EACA,iBAAiB,WAAW,oBAAoB;EAChD,qBAAqB,WAAW,wBAAwB;EACzD;;;;ACxDH,MAAMA,SAAO,KAAK,IAAI,IAAI,OAAO;AACjC,MAAMC,iBACJ,OAAOD,WAAS,WAAW,EAAE,MAAM,SAASA,QAAM,GAAG,EAAE,GAAG,EAAE;AAC9D,MAAM,4BAA4B;AAMlC,SAAgB,+BACd,SACe;CACf,MAAM,EAAE,SAAS,uBAAuB;CACxC,MAAM,oBAAoB,6BAA6B;CACvD,MAAM,SAAS,KAAK,MAAMC,iBAAe,YAAY;EACnD,MAAM,MAAM,IAAI,MAAM;EAEtB,6BAA6B;GAC3B,KAAK,IAAI,SAAS,0BAA0B;GAC5C;GACA,UAAU;GACV;GACA;GACD,CAAC;EAEF,OAAO,IAAI,MAAM,QAAQ;GACzB;CAEF,QAAQ,IAAI,kCAAkC,OAAO,KAAK,OAAO;CACjE,OAAO,QAAQ,SAAS;;;;;;;;;ACtB1B,eAAsB,4BACpB,SACe;CACf,uCAAuC,QAAQ,OAAO;CACtD,MAAM,YAAY,aAAa,EAC7B,QAAQ,YACN,+BAA+B;EAC7B,GAAG;EACH,oBAAoB,QAAQ;EAC7B,CAAC,EACL,EAAE;;;;ACnBL,MAAM,OAAO,KAAK,IAAI,IAAI,OAAO;AACjC,MAAM,eACJ,OAAO,SAAS,WAAW,EAAE,MAAM,SAAS,MAAM,GAAG,EAAE,GAAG,EAAE;;;;;;;AAuB9D,SAAgB,uBACd,SACkB;CAClB,MAAM,EAAE,UAAU,gBAAgB,WAAW;CAE7C,QAAQ,EAAE,cAAc;EACtB,KAAK,MACH,cACA,+BAA+B;GAC7B;GACA,GAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,GAAG,EAAE;GAC1C,iBAAiB,QAAQ;IACvB,eAAe,IAAI,SAAS,SAAS,CAAC;;GAEzC,CAAC,CACH;EAED,QAAQ,IACN,iBAAiB,SAAS,kCAAkC,OAC7D;EACD,OAAO,QAAQ,SAAS"}
@@ -1,6 +1,128 @@
1
- import { JwkSet } from "./types.js";
2
- import { getJwkThumbprint } from "./utils/jwk-utils.js";
3
- import { verifyDpopProof } from "./utils/dpop-utils.js";
4
- import { signJwt, verifyJwt } from "./utils/jwt-utils.js";
5
- import { sha256base64url } from "./shared/encoding/sha256.js";
6
- export { type JwkSet, getJwkThumbprint, sha256base64url, signJwt, verifyDpopProof, verifyJwt };
1
+ import { r as JwkSet } from "./types-5gfN91Fq.js";
2
+
3
+ //#region src/server/utils/jwk-utils.d.ts
4
+ interface GetJwkThumbprintOptions {
5
+ /** EC P-256 public JWK whose thumbprint to compute. */
6
+ publicKeyJwk: JsonWebKey;
7
+ }
8
+ /**
9
+ * Computes the RFC 7638 JWK thumbprint of an EC P-256 public JWK.
10
+ * Per §3.2 the canonical form contains only `crv`, `kty`, `x`, `y`,
11
+ * sorted lexicographically — no whitespace, no other members. The
12
+ * SHA-256 of this canonical UTF-8 JSON, base64url-encoded, is the
13
+ * stable identifier (`jkt`) DPoP uses to bind tokens to public keys.
14
+ */
15
+ declare function getJwkThumbprint(options: GetJwkThumbprintOptions): Promise<string>;
16
+ //#endregion
17
+ //#region src/server/utils/dpop-utils.d.ts
18
+ /**
19
+ * Claims that go into a DPoP proof JWT (RFC 9449 §4.2). Extra
20
+ * properties pass through to the encoder unchanged so callers can
21
+ * include implementation-specific claims.
22
+ */
23
+ interface DpopClaims {
24
+ /** HTTP method of the protected request, uppercase. */
25
+ htm: string;
26
+ /** Target URI of the protected request, fully-qualified. */
27
+ htu: string;
28
+ /** Unique proof identifier (RFC 9449 §4.2, recommended UUID). */
29
+ jti: string;
30
+ /** Issuance time, Unix epoch seconds. */
31
+ iat: number;
32
+ /**
33
+ * Hash of the access token presented alongside this proof, if any
34
+ * (RFC 9449 §4.2). Required for resource-server DPoP.
35
+ */
36
+ ath?: string;
37
+ /**
38
+ * App session ID hash. Custom HubSpot extension that lets the auth
39
+ * server bind tokens to the browser session that minted them.
40
+ */
41
+ sid?: string;
42
+ [key: string]: unknown;
43
+ }
44
+ /**
45
+ * Result of a successful {@link verifyDpopProof} call.
46
+ */
47
+ interface VerifiedDpopProof {
48
+ /** Public JWK extracted from the proof's header. */
49
+ publicKeyJwk: JsonWebKey;
50
+ /** RFC 7638 JWK thumbprint of `publicKeyJwk`. */
51
+ jkt: string;
52
+ /** Decoded claims from the proof's payload. */
53
+ claims: DpopClaims;
54
+ }
55
+ interface VerifyDpopProofOptions {
56
+ /** The compact-serialized DPoP proof. */
57
+ proof: string;
58
+ /** Expected HTTP method (RFC 9449 `htm` claim). */
59
+ htm: string;
60
+ /** Expected request URI (RFC 9449 `htu` claim). */
61
+ htu: string;
62
+ /** Expected access-token hash (RFC 9449 `ath` claim). */
63
+ ath?: string;
64
+ /** Expected app-session-ID hash (`sid` claim). */
65
+ sid?: string;
66
+ }
67
+ /**
68
+ * Verifies a DPoP proof JWT and returns the embedded public JWK,
69
+ * its thumbprint, and the decoded claims.
70
+ *
71
+ * Enforces RFC 9449's required checks:
72
+ *
73
+ * - `typ=dpop+jwt`, `alg=ES256`, and a JWK in the header.
74
+ * - Signature is valid against the embedded JWK.
75
+ * - `htm`, `htu`, and (when supplied) `ath`/`sid` match.
76
+ * - `iat` is within ±5 minutes of "now".
77
+ *
78
+ * @throws {Error} If any of the above checks fail.
79
+ */
80
+ declare function verifyDpopProof(options: VerifyDpopProofOptions): Promise<VerifiedDpopProof>;
81
+ //#endregion
82
+ //#region src/server/utils/jwt-utils.d.ts
83
+ interface VerifyJwtOptions {
84
+ /** Compact-serialized JWT to verify. */
85
+ token: string;
86
+ /** Public key in JWK form. Caller is responsible for trusting it. */
87
+ publicKeyJwk: JsonWebKey;
88
+ }
89
+ /**
90
+ * Verifies signature and (if present) `exp` (RFC 7519 §4.1.4) on a
91
+ * JWT and returns its payload.
92
+ *
93
+ * @throws {Error} When the signature fails or when `exp` has passed.
94
+ */
95
+ declare function verifyJwt(options: VerifyJwtOptions): Promise<Record<string, unknown>>;
96
+ interface SignJwtOptions {
97
+ /** ES256 private key as a non-extractable WebCrypto key. */
98
+ privateKey: CryptoKey;
99
+ /**
100
+ * Custom claims merged onto an `iat` claim (and `exp` when
101
+ * `ttlSeconds` is supplied). Caller-provided keys override the
102
+ * standard ones.
103
+ */
104
+ payload: Record<string, unknown>;
105
+ /**
106
+ * Lifetime of the token in seconds. When set, the JWT's `exp` claim
107
+ * is computed as `iat + ttlSeconds`. When omitted, no `exp` is added
108
+ * (the caller is responsible for one if needed).
109
+ */
110
+ ttlSeconds?: number;
111
+ }
112
+ /**
113
+ * Signs a JWT (RFC 7519) with `alg=ES256, typ=JWT` and returns the
114
+ * compact serialization. Always sets `iat` to the current second; the
115
+ * caller controls every other claim via `payload`.
116
+ */
117
+ declare function signJwt(options: SignJwtOptions): Promise<string>;
118
+ //#endregion
119
+ //#region src/shared/encoding/sha256.d.ts
120
+ /**
121
+ * Hashes a UTF-8 string with SHA-256 and encodes the digest as
122
+ * base64url. Used to compute DPoP `ath`/`sid` claims, JWK thumbprints
123
+ * (RFC 7638), and PKCE code challenges.
124
+ */
125
+ declare function sha256base64url(input: string): Promise<string>;
126
+ //#endregion
127
+ export { type JwkSet, getJwkThumbprint, sha256base64url, signJwt, verifyDpopProof, verifyJwt };
128
+ //# sourceMappingURL=oauth.d.ts.map
@@ -1,5 +1,2 @@
1
- import { getJwkThumbprint } from "./utils/jwk-utils.js";
2
- import { signJwt, verifyJwt } from "./utils/jwt-utils.js";
3
- import { verifyDpopProof } from "./utils/dpop-utils.js";
4
- import { sha256base64url } from "./shared/encoding/sha256.js";
1
+ import { a as verifyJwt, i as signJwt, o as getJwkThumbprint, r as verifyDpopProof, t as sha256base64url } from "./sha256-B7y8GBFB.js";
5
2
  export { getJwkThumbprint, sha256base64url, signJwt, verifyDpopProof, verifyJwt };
@@ -0,0 +1,228 @@
1
+ //#region src/shared/encoding/base64.ts
2
+ /**
3
+ * Base64url encoding and decoding helpers shared by the browser and
4
+ * server halves of `@hubspot/app-connect-sdk`.
5
+ *
6
+ * Base64url (RFC 4648 §5) replaces `+`/`/` with `-`/`_` and drops `=`
7
+ * padding. JWT, DPoP, and JWK thumbprints all use this variant.
8
+ */
9
+ /**
10
+ * Encodes a binary buffer as a base64url string (RFC 4648 §5).
11
+ */
12
+ function base64url(input) {
13
+ const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
14
+ let binary = "";
15
+ for (const byte of bytes) binary += String.fromCharCode(byte);
16
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
17
+ }
18
+ /**
19
+ * Decodes a base64url string into a `Uint8Array`. Tolerates missing
20
+ * padding by re-adding it before delegating to `atob`.
21
+ */
22
+ function base64urlDecode(encoded) {
23
+ const padLen = (4 - encoded.length % 4) % 4;
24
+ const padded = encoded.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat(padLen);
25
+ const binary = atob(padded);
26
+ const out = new Uint8Array(new ArrayBuffer(binary.length));
27
+ for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i) ?? 0;
28
+ return out;
29
+ }
30
+ /**
31
+ * Decodes a *standard* base64 string (with `+`/`/` and required `=`
32
+ * padding) into an `ArrayBuffer`. Used for PKCS8-encoded private keys
33
+ * stored in environment variables.
34
+ */
35
+ function base64StandardToArrayBuffer(b64) {
36
+ const bin = atob(b64);
37
+ const buf = new ArrayBuffer(bin.length);
38
+ const view = new Uint8Array(buf);
39
+ for (let i = 0; i < bin.length; i++) view[i] = bin.charCodeAt(i) ?? 0;
40
+ return buf;
41
+ }
42
+ //#endregion
43
+ //#region src/server/utils/jwk-utils.ts
44
+ /**
45
+ * Computes the RFC 7638 JWK thumbprint of an EC P-256 public JWK.
46
+ * Per §3.2 the canonical form contains only `crv`, `kty`, `x`, `y`,
47
+ * sorted lexicographically — no whitespace, no other members. The
48
+ * SHA-256 of this canonical UTF-8 JSON, base64url-encoded, is the
49
+ * stable identifier (`jkt`) DPoP uses to bind tokens to public keys.
50
+ */
51
+ async function getJwkThumbprint(options) {
52
+ const { publicKeyJwk } = options;
53
+ const canonical = JSON.stringify({
54
+ crv: publicKeyJwk.crv,
55
+ kty: publicKeyJwk.kty,
56
+ x: publicKeyJwk.x,
57
+ y: publicKeyJwk.y
58
+ });
59
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonical));
60
+ return base64url(new Uint8Array(digest));
61
+ }
62
+ //#endregion
63
+ //#region src/server/utils/jwt-utils.ts
64
+ /**
65
+ * Low-level helper that encodes a JWS Compact Serialization JWT
66
+ * (RFC 7519) and signs it with the supplied `privateKey` using
67
+ * ES256 (P-256 + SHA-256). Returns the three-segment compact form.
68
+ */
69
+ async function encodeAndSignJwt(options) {
70
+ const { header, payload, privateKey } = options;
71
+ const signingInput = `${base64url(new TextEncoder().encode(JSON.stringify(header)))}.${base64url(new TextEncoder().encode(JSON.stringify(payload)))}`;
72
+ const signatureBuffer = await crypto.subtle.sign({
73
+ name: "ECDSA",
74
+ hash: "SHA-256"
75
+ }, privateKey, new TextEncoder().encode(signingInput));
76
+ return `${signingInput}.${base64url(new Uint8Array(signatureBuffer))}`;
77
+ }
78
+ async function importPublicKey(jwk) {
79
+ return crypto.subtle.importKey("jwk", jwk, {
80
+ name: "ECDSA",
81
+ namedCurve: "P-256"
82
+ }, false, ["verify"]);
83
+ }
84
+ /**
85
+ * Verifies the ES256 signature on `token` against `publicKeyJwk` and
86
+ * returns the decoded payload. Does not check `exp` — use
87
+ * {@link verifyJwt} when expiry enforcement is desired.
88
+ *
89
+ * @throws {Error} When the token isn't three segments, when the
90
+ * signature fails verification, or when the payload isn't valid
91
+ * JSON.
92
+ */
93
+ async function decodeAndVerifyJwt(options) {
94
+ const { token, publicKeyJwk } = options;
95
+ const parts = token.split(".");
96
+ if (parts.length !== 3) throw new Error("Invalid JWT format");
97
+ const [encodedHeader, encodedPayload, encodedSignature] = parts;
98
+ const publicKey = await importPublicKey(publicKeyJwk);
99
+ if (!await crypto.subtle.verify({
100
+ name: "ECDSA",
101
+ hash: "SHA-256"
102
+ }, publicKey, base64urlDecode(encodedSignature), new TextEncoder().encode(`${encodedHeader}.${encodedPayload}`))) throw new Error("JWT signature verification failed");
103
+ return JSON.parse(new TextDecoder().decode(base64urlDecode(encodedPayload)));
104
+ }
105
+ /**
106
+ * Verifies signature and (if present) `exp` (RFC 7519 §4.1.4) on a
107
+ * JWT and returns its payload.
108
+ *
109
+ * @throws {Error} When the signature fails or when `exp` has passed.
110
+ */
111
+ async function verifyJwt(options) {
112
+ const { token, publicKeyJwk } = options;
113
+ const payload = await decodeAndVerifyJwt({
114
+ token,
115
+ publicKeyJwk
116
+ });
117
+ const now = Math.floor(Date.now() / 1e3);
118
+ if (typeof payload["exp"] === "number" && payload["exp"] < now) throw new Error("JWT expired");
119
+ return payload;
120
+ }
121
+ /**
122
+ * Signs a JWT (RFC 7519) with `alg=ES256, typ=JWT` and returns the
123
+ * compact serialization. Always sets `iat` to the current second; the
124
+ * caller controls every other claim via `payload`.
125
+ */
126
+ async function signJwt(options) {
127
+ const { privateKey, payload, ttlSeconds } = options;
128
+ const now = Math.floor(Date.now() / 1e3);
129
+ return encodeAndSignJwt({
130
+ header: {
131
+ alg: "ES256",
132
+ typ: "JWT"
133
+ },
134
+ payload: ttlSeconds !== void 0 ? {
135
+ iat: now,
136
+ exp: now + ttlSeconds,
137
+ ...payload
138
+ } : {
139
+ iat: now,
140
+ ...payload
141
+ },
142
+ privateKey
143
+ });
144
+ }
145
+ //#endregion
146
+ //#region src/server/utils/dpop-utils.ts
147
+ function ecPublicJwkForDpopHeader(jwk) {
148
+ if (jwk.kty !== "EC" || jwk.crv !== "P-256" || typeof jwk.x !== "string" || typeof jwk.y !== "string") throw new Error("Expected P-256 EC public JWK");
149
+ return {
150
+ kty: "EC",
151
+ crv: "P-256",
152
+ x: jwk.x,
153
+ y: jwk.y
154
+ };
155
+ }
156
+ /**
157
+ * Mints a DPoP proof JWT (RFC 9449) signed with the app's private
158
+ * key. The header is set to `typ=dpop+jwt`, `alg=ES256`, and embeds
159
+ * the public JWK so the receiver can verify the signature without
160
+ * out-of-band key distribution.
161
+ */
162
+ async function signDpopProof(options) {
163
+ const { appKeys, claims } = options;
164
+ return encodeAndSignJwt({
165
+ header: {
166
+ alg: "ES256",
167
+ typ: "dpop+jwt",
168
+ jwk: ecPublicJwkForDpopHeader(appKeys.appPublicKeyJwk)
169
+ },
170
+ payload: claims,
171
+ privateKey: appKeys.appPrivateKey
172
+ });
173
+ }
174
+ /**
175
+ * Verifies a DPoP proof JWT and returns the embedded public JWK,
176
+ * its thumbprint, and the decoded claims.
177
+ *
178
+ * Enforces RFC 9449's required checks:
179
+ *
180
+ * - `typ=dpop+jwt`, `alg=ES256`, and a JWK in the header.
181
+ * - Signature is valid against the embedded JWK.
182
+ * - `htm`, `htu`, and (when supplied) `ath`/`sid` match.
183
+ * - `iat` is within ±5 minutes of "now".
184
+ *
185
+ * @throws {Error} If any of the above checks fail.
186
+ */
187
+ async function verifyDpopProof(options) {
188
+ const { proof, htm, htu, ath, sid } = options;
189
+ const parts = proof.split(".");
190
+ if (parts.length !== 3) throw new Error("Invalid DPoP proof format");
191
+ const encodedHeader = parts[0];
192
+ if (!encodedHeader) throw new Error("Missing DPoP header");
193
+ const header = JSON.parse(new TextDecoder().decode(base64urlDecode(encodedHeader)));
194
+ if (header.typ !== "dpop+jwt") throw new Error("Invalid DPoP typ header");
195
+ if (header.alg !== "ES256") throw new Error("Unsupported DPoP algorithm");
196
+ const publicKeyJwk = header.jwk;
197
+ if (!publicKeyJwk) throw new Error("Missing jwk in DPoP header");
198
+ const claims = await decodeAndVerifyJwt({
199
+ token: proof,
200
+ publicKeyJwk
201
+ });
202
+ if (claims.htm !== htm) throw new Error(`DPoP htm mismatch: expected ${htm}, got ${claims.htm}`);
203
+ if (claims.htu !== htu) throw new Error(`DPoP htu mismatch: expected ${htu}, got ${claims.htu}`);
204
+ if (ath !== void 0 && claims.ath !== ath) throw new Error("DPoP ath mismatch");
205
+ if (sid !== void 0 && claims.sid !== sid) throw new Error("DPoP sid mismatch");
206
+ const now = Math.floor(Date.now() / 1e3);
207
+ if (Math.abs(now - claims.iat) > 300) throw new Error("DPoP proof expired or too far in future");
208
+ return {
209
+ publicKeyJwk,
210
+ jkt: await getJwkThumbprint({ publicKeyJwk }),
211
+ claims
212
+ };
213
+ }
214
+ //#endregion
215
+ //#region src/shared/encoding/sha256.ts
216
+ /**
217
+ * Hashes a UTF-8 string with SHA-256 and encodes the digest as
218
+ * base64url. Used to compute DPoP `ath`/`sid` claims, JWK thumbprints
219
+ * (RFC 7638), and PKCE code challenges.
220
+ */
221
+ async function sha256base64url(input) {
222
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
223
+ return base64url(new Uint8Array(digest));
224
+ }
225
+ //#endregion
226
+ export { verifyJwt as a, base64url as c, signJwt as i, base64urlDecode as l, signDpopProof as n, getJwkThumbprint as o, verifyDpopProof as r, base64StandardToArrayBuffer as s, sha256base64url as t };
227
+
228
+ //# sourceMappingURL=sha256-B7y8GBFB.js.map