@atproto/oauth-provider 0.19.9 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/account/account-manager.d.ts +11 -11
  3. package/dist/account/account-manager.d.ts.map +1 -1
  4. package/dist/account/account-manager.js.map +1 -1
  5. package/dist/account/account-store.d.ts +5 -10
  6. package/dist/account/account-store.d.ts.map +1 -1
  7. package/dist/account/account-store.js +0 -5
  8. package/dist/account/account-store.js.map +1 -1
  9. package/dist/client/client-auth.d.ts +1 -1
  10. package/dist/client/client-auth.d.ts.map +1 -1
  11. package/dist/client/client-auth.js.map +1 -1
  12. package/dist/client/client-data.d.ts +2 -2
  13. package/dist/client/client-data.d.ts.map +1 -1
  14. package/dist/client/client-data.js.map +1 -1
  15. package/dist/client/client-id.d.ts +1 -1
  16. package/dist/client/client-id.d.ts.map +1 -1
  17. package/dist/client/client-id.js.map +1 -1
  18. package/dist/client/client-manager.d.ts +8 -8
  19. package/dist/client/client-manager.d.ts.map +1 -1
  20. package/dist/client/client-manager.js +1 -1
  21. package/dist/client/client-manager.js.map +1 -1
  22. package/dist/client/client-store.d.ts +4 -6
  23. package/dist/client/client-store.d.ts.map +1 -1
  24. package/dist/client/client-store.js +0 -3
  25. package/dist/client/client-store.js.map +1 -1
  26. package/dist/client/client-utils.d.ts +1 -1
  27. package/dist/client/client-utils.d.ts.map +1 -1
  28. package/dist/client/client-utils.js.map +1 -1
  29. package/dist/client/client.d.ts +6 -6
  30. package/dist/client/client.d.ts.map +1 -1
  31. package/dist/client/client.js +1 -1
  32. package/dist/client/client.js.map +1 -1
  33. package/dist/customization/branding.d.ts +1 -1
  34. package/dist/customization/branding.d.ts.map +1 -1
  35. package/dist/customization/branding.js.map +1 -1
  36. package/dist/customization/build-customization-css.d.ts +1 -1
  37. package/dist/customization/build-customization-css.d.ts.map +1 -1
  38. package/dist/customization/build-customization-css.js.map +1 -1
  39. package/dist/customization/customization.d.ts +1 -1
  40. package/dist/customization/customization.d.ts.map +1 -1
  41. package/dist/customization/customization.js.map +1 -1
  42. package/dist/device/device-data.d.ts +2 -0
  43. package/dist/device/device-data.d.ts.map +1 -1
  44. package/dist/device/device-data.js.map +1 -1
  45. package/dist/device/device-id.js +1 -1
  46. package/dist/device/device-id.js.map +1 -1
  47. package/dist/device/device-manager.d.ts +3 -3
  48. package/dist/device/device-manager.d.ts.map +1 -1
  49. package/dist/device/device-manager.js +1 -1
  50. package/dist/device/device-manager.js.map +1 -1
  51. package/dist/device/device-store.d.ts +5 -7
  52. package/dist/device/device-store.d.ts.map +1 -1
  53. package/dist/device/device-store.js +0 -4
  54. package/dist/device/device-store.js.map +1 -1
  55. package/dist/device/session-id.d.ts.map +1 -1
  56. package/dist/device/session-id.js +1 -1
  57. package/dist/device/session-id.js.map +1 -1
  58. package/dist/dpop/dpop-manager.d.ts +2 -2
  59. package/dist/dpop/dpop-manager.d.ts.map +1 -1
  60. package/dist/dpop/dpop-manager.js +1 -1
  61. package/dist/dpop/dpop-manager.js.map +1 -1
  62. package/dist/dpop/dpop-nonce.js +1 -1
  63. package/dist/dpop/dpop-nonce.js.map +1 -1
  64. package/dist/errors/access-denied-error.d.ts +1 -1
  65. package/dist/errors/access-denied-error.d.ts.map +1 -1
  66. package/dist/errors/access-denied-error.js.map +1 -1
  67. package/dist/errors/account-selection-required-error.d.ts +1 -1
  68. package/dist/errors/account-selection-required-error.d.ts.map +1 -1
  69. package/dist/errors/account-selection-required-error.js.map +1 -1
  70. package/dist/errors/authorization-error.d.ts +2 -2
  71. package/dist/errors/authorization-error.d.ts.map +1 -1
  72. package/dist/errors/authorization-error.js.map +1 -1
  73. package/dist/errors/consent-required-error.d.ts +1 -1
  74. package/dist/errors/consent-required-error.d.ts.map +1 -1
  75. package/dist/errors/consent-required-error.js.map +1 -1
  76. package/dist/errors/handle-unavailable-error.d.ts +1 -1
  77. package/dist/errors/handle-unavailable-error.d.ts.map +1 -1
  78. package/dist/errors/handle-unavailable-error.js.map +1 -1
  79. package/dist/errors/invalid-authorization-details-error.d.ts +1 -1
  80. package/dist/errors/invalid-authorization-details-error.d.ts.map +1 -1
  81. package/dist/errors/invalid-authorization-details-error.js.map +1 -1
  82. package/dist/errors/invalid-client-metadata-error.js +1 -1
  83. package/dist/errors/invalid-client-metadata-error.js.map +1 -1
  84. package/dist/errors/invalid-credentials-error.d.ts +1 -1
  85. package/dist/errors/invalid-credentials-error.d.ts.map +1 -1
  86. package/dist/errors/invalid-credentials-error.js.map +1 -1
  87. package/dist/errors/invalid-scope-error.d.ts +1 -1
  88. package/dist/errors/invalid-scope-error.d.ts.map +1 -1
  89. package/dist/errors/invalid-scope-error.js.map +1 -1
  90. package/dist/errors/login-required-error.d.ts +1 -1
  91. package/dist/errors/login-required-error.d.ts.map +1 -1
  92. package/dist/errors/login-required-error.js.map +1 -1
  93. package/dist/lexicon/lexicon-data.d.ts +1 -1
  94. package/dist/lexicon/lexicon-data.d.ts.map +1 -1
  95. package/dist/lexicon/lexicon-data.js.map +1 -1
  96. package/dist/lexicon/lexicon-getter.d.ts +3 -3
  97. package/dist/lexicon/lexicon-getter.d.ts.map +1 -1
  98. package/dist/lexicon/lexicon-getter.js +1 -1
  99. package/dist/lexicon/lexicon-getter.js.map +1 -1
  100. package/dist/lexicon/lexicon-manager.d.ts +4 -4
  101. package/dist/lexicon/lexicon-manager.d.ts.map +1 -1
  102. package/dist/lexicon/lexicon-manager.js.map +1 -1
  103. package/dist/lexicon/lexicon-store.d.ts +4 -3
  104. package/dist/lexicon/lexicon-store.d.ts.map +1 -1
  105. package/dist/lexicon/lexicon-store.js.map +1 -1
  106. package/dist/lib/csp/index.d.ts +1 -1
  107. package/dist/lib/csp/index.d.ts.map +1 -1
  108. package/dist/lib/csp/index.js.map +1 -1
  109. package/dist/lib/hcaptcha.d.ts +1 -1
  110. package/dist/lib/hcaptcha.d.ts.map +1 -1
  111. package/dist/lib/hcaptcha.js +1 -1
  112. package/dist/lib/hcaptcha.js.map +1 -1
  113. package/dist/lib/html/build-document.d.ts +1 -1
  114. package/dist/lib/html/build-document.d.ts.map +1 -1
  115. package/dist/lib/html/build-document.js.map +1 -1
  116. package/dist/lib/html/escapers.d.ts +1 -1
  117. package/dist/lib/html/escapers.d.ts.map +1 -1
  118. package/dist/lib/html/escapers.js.map +1 -1
  119. package/dist/lib/html/tags.d.ts +1 -1
  120. package/dist/lib/html/tags.d.ts.map +1 -1
  121. package/dist/lib/html/tags.js +1 -0
  122. package/dist/lib/html/tags.js.map +1 -1
  123. package/dist/lib/http/accept.d.ts +2 -2
  124. package/dist/lib/http/accept.d.ts.map +1 -1
  125. package/dist/lib/http/accept.js.map +1 -1
  126. package/dist/lib/http/middleware.d.ts +1 -1
  127. package/dist/lib/http/middleware.d.ts.map +1 -1
  128. package/dist/lib/http/middleware.js.map +1 -1
  129. package/dist/lib/http/request.d.ts +2 -2
  130. package/dist/lib/http/request.d.ts.map +1 -1
  131. package/dist/lib/http/request.js.map +1 -1
  132. package/dist/lib/http/response.d.ts +1 -1
  133. package/dist/lib/http/response.d.ts.map +1 -1
  134. package/dist/lib/http/response.js.map +1 -1
  135. package/dist/lib/http/route.d.ts +4 -4
  136. package/dist/lib/http/route.d.ts.map +1 -1
  137. package/dist/lib/http/route.js.map +1 -1
  138. package/dist/lib/http/router.d.ts +5 -5
  139. package/dist/lib/http/router.d.ts.map +1 -1
  140. package/dist/lib/http/router.js.map +1 -1
  141. package/dist/lib/http/stream.d.ts +2 -2
  142. package/dist/lib/http/stream.d.ts.map +1 -1
  143. package/dist/lib/http/stream.js.map +1 -1
  144. package/dist/lib/util/time.d.ts +1 -1
  145. package/dist/lib/util/time.d.ts.map +1 -1
  146. package/dist/lib/util/time.js.map +1 -1
  147. package/dist/lib/util/zod-error.d.ts +1 -1
  148. package/dist/lib/util/zod-error.d.ts.map +1 -1
  149. package/dist/lib/util/zod-error.js.map +1 -1
  150. package/dist/lib/write-form-redirect.d.ts +1 -1
  151. package/dist/lib/write-form-redirect.d.ts.map +1 -1
  152. package/dist/lib/write-form-redirect.js.map +1 -1
  153. package/dist/lib/write-html.d.ts +3 -3
  154. package/dist/lib/write-html.d.ts.map +1 -1
  155. package/dist/lib/write-html.js.map +1 -1
  156. package/dist/metadata/build-metadata.d.ts +2 -2
  157. package/dist/metadata/build-metadata.d.ts.map +1 -1
  158. package/dist/metadata/build-metadata.js.map +1 -1
  159. package/dist/{constants.d.ts → oauth-constants.d.ts} +1 -1
  160. package/dist/oauth-constants.d.ts.map +1 -0
  161. package/dist/{constants.js → oauth-constants.js} +1 -1
  162. package/dist/oauth-constants.js.map +1 -0
  163. package/dist/oauth-errors.d.ts +2 -3
  164. package/dist/oauth-errors.d.ts.map +1 -1
  165. package/dist/oauth-errors.js +4 -4
  166. package/dist/oauth-errors.js.map +1 -1
  167. package/dist/oauth-hooks.d.ts +20 -24
  168. package/dist/oauth-hooks.d.ts.map +1 -1
  169. package/dist/oauth-hooks.js +1 -8
  170. package/dist/oauth-hooks.js.map +1 -1
  171. package/dist/oauth-middleware.d.ts +4 -4
  172. package/dist/oauth-middleware.d.ts.map +1 -1
  173. package/dist/oauth-middleware.js.map +1 -1
  174. package/dist/oauth-provider.d.ts +46 -37
  175. package/dist/oauth-provider.d.ts.map +1 -1
  176. package/dist/oauth-provider.js +17 -8
  177. package/dist/oauth-provider.js.map +1 -1
  178. package/dist/oauth-store.d.ts +0 -4
  179. package/dist/oauth-store.d.ts.map +1 -1
  180. package/dist/oauth-store.js +0 -4
  181. package/dist/oauth-store.js.map +1 -1
  182. package/dist/oauth-utils.d.ts +14 -0
  183. package/dist/oauth-utils.d.ts.map +1 -0
  184. package/dist/oauth-utils.js +5 -0
  185. package/dist/oauth-utils.js.map +1 -0
  186. package/dist/oauth-verifier.d.ts +6 -6
  187. package/dist/oauth-verifier.d.ts.map +1 -1
  188. package/dist/oauth-verifier.js.map +1 -1
  189. package/dist/replay/replay-manager.d.ts +2 -2
  190. package/dist/replay/replay-manager.d.ts.map +1 -1
  191. package/dist/replay/replay-manager.js +1 -1
  192. package/dist/replay/replay-manager.js.map +1 -1
  193. package/dist/replay/replay-store-redis.d.ts +1 -1
  194. package/dist/replay/replay-store-redis.d.ts.map +1 -1
  195. package/dist/replay/replay-store-redis.js.map +1 -1
  196. package/dist/replay/replay-store.d.ts +1 -1
  197. package/dist/replay/replay-store.d.ts.map +1 -1
  198. package/dist/replay/replay-store.js.map +1 -1
  199. package/dist/request/code.js +1 -1
  200. package/dist/request/code.js.map +1 -1
  201. package/dist/request/request-data.d.ts +7 -7
  202. package/dist/request/request-data.d.ts.map +1 -1
  203. package/dist/request/request-data.js.map +1 -1
  204. package/dist/request/request-id.d.ts.map +1 -1
  205. package/dist/request/request-id.js +1 -1
  206. package/dist/request/request-id.js.map +1 -1
  207. package/dist/request/request-manager.d.ts +13 -13
  208. package/dist/request/request-manager.d.ts.map +1 -1
  209. package/dist/request/request-manager.js +1 -1
  210. package/dist/request/request-manager.js.map +1 -1
  211. package/dist/request/request-store.d.ts +6 -8
  212. package/dist/request/request-store.d.ts.map +1 -1
  213. package/dist/request/request-store.js +0 -4
  214. package/dist/request/request-store.js.map +1 -1
  215. package/dist/request/request-uri.d.ts +1 -1
  216. package/dist/request/request-uri.d.ts.map +1 -1
  217. package/dist/request/request-uri.js.map +1 -1
  218. package/dist/result/authorization-redirect-parameters.d.ts +2 -2
  219. package/dist/result/authorization-redirect-parameters.d.ts.map +1 -1
  220. package/dist/result/authorization-redirect-parameters.js.map +1 -1
  221. package/dist/result/authorization-result-redirect.d.ts +2 -2
  222. package/dist/result/authorization-result-redirect.d.ts.map +1 -1
  223. package/dist/result/authorization-result-redirect.js.map +1 -1
  224. package/dist/router/assets/assets-manifest.d.ts +2 -2
  225. package/dist/router/assets/assets-manifest.d.ts.map +1 -1
  226. package/dist/router/assets/assets-manifest.js.map +1 -1
  227. package/dist/router/assets/assets.d.ts +4 -4
  228. package/dist/router/assets/assets.d.ts.map +1 -1
  229. package/dist/router/assets/assets.js.map +1 -1
  230. package/dist/router/assets/csrf.js.map +1 -1
  231. package/dist/router/assets/send-account-page.d.ts +2 -2
  232. package/dist/router/assets/send-account-page.d.ts.map +1 -1
  233. package/dist/router/assets/send-account-page.js.map +1 -1
  234. package/dist/router/assets/send-authorization-page.d.ts +3 -3
  235. package/dist/router/assets/send-authorization-page.d.ts.map +1 -1
  236. package/dist/router/assets/send-authorization-page.js.map +1 -1
  237. package/dist/router/assets/send-cookie-error-page.d.ts +2 -2
  238. package/dist/router/assets/send-cookie-error-page.d.ts.map +1 -1
  239. package/dist/router/assets/send-cookie-error-page.js.map +1 -1
  240. package/dist/router/assets/send-error-page.d.ts +2 -2
  241. package/dist/router/assets/send-error-page.d.ts.map +1 -1
  242. package/dist/router/assets/send-error-page.js.map +1 -1
  243. package/dist/router/assets/send-redirect.d.ts +4 -4
  244. package/dist/router/assets/send-redirect.d.ts.map +1 -1
  245. package/dist/router/assets/send-redirect.js.map +1 -1
  246. package/dist/router/create-account-page-middleware.d.ts +1 -1
  247. package/dist/router/create-account-page-middleware.d.ts.map +1 -1
  248. package/dist/router/create-account-page-middleware.js.map +1 -1
  249. package/dist/router/create-api-middleware.d.ts +2 -2
  250. package/dist/router/create-api-middleware.d.ts.map +1 -1
  251. package/dist/router/create-api-middleware.js +1 -1
  252. package/dist/router/create-api-middleware.js.map +1 -1
  253. package/dist/router/create-authorization-page-middleware.d.ts +1 -1
  254. package/dist/router/create-authorization-page-middleware.d.ts.map +1 -1
  255. package/dist/router/create-authorization-page-middleware.js.map +1 -1
  256. package/dist/router/create-oauth-middleware.d.ts +1 -1
  257. package/dist/router/create-oauth-middleware.d.ts.map +1 -1
  258. package/dist/router/create-oauth-middleware.js +1 -1
  259. package/dist/router/create-oauth-middleware.js.map +1 -1
  260. package/dist/signer/api-token-payload.d.ts +1 -1
  261. package/dist/signer/api-token-payload.d.ts.map +1 -1
  262. package/dist/signer/api-token-payload.js +1 -1
  263. package/dist/signer/api-token-payload.js.map +1 -1
  264. package/dist/signer/signer.d.ts +4 -4
  265. package/dist/signer/signer.d.ts.map +1 -1
  266. package/dist/signer/signer.js +2 -2
  267. package/dist/signer/signer.js.map +1 -1
  268. package/dist/token/refresh-token.js +1 -1
  269. package/dist/token/refresh-token.js.map +1 -1
  270. package/dist/token/token-claims.d.ts +4 -4
  271. package/dist/token/token-claims.d.ts.map +1 -1
  272. package/dist/token/token-claims.js.map +1 -1
  273. package/dist/token/token-data.d.ts +7 -7
  274. package/dist/token/token-data.d.ts.map +1 -1
  275. package/dist/token/token-data.js.map +1 -1
  276. package/dist/token/token-id.js +1 -1
  277. package/dist/token/token-id.js.map +1 -1
  278. package/dist/token/token-manager.d.ts +14 -14
  279. package/dist/token/token-manager.d.ts.map +1 -1
  280. package/dist/token/token-manager.js +1 -1
  281. package/dist/token/token-manager.js.map +1 -1
  282. package/dist/token/token-store.d.ts +7 -9
  283. package/dist/token/token-store.d.ts.map +1 -1
  284. package/dist/token/token-store.js +0 -4
  285. package/dist/token/token-store.js.map +1 -1
  286. package/dist/types/handle.js.map +1 -1
  287. package/dist/types/rgb-color.d.ts +1 -1
  288. package/dist/types/rgb-color.d.ts.map +1 -1
  289. package/dist/types/rgb-color.js.map +1 -1
  290. package/package.json +47 -20
  291. package/dist/constants.d.ts.map +0 -1
  292. package/dist/constants.js.map +0 -1
  293. package/dist/errors/invalid-invite-code-error.d.ts +0 -5
  294. package/dist/errors/invalid-invite-code-error.d.ts.map +0 -1
  295. package/dist/errors/invalid-invite-code-error.js +0 -7
  296. package/dist/errors/invalid-invite-code-error.js.map +0 -1
  297. package/dist/index.d.ts +0 -15
  298. package/dist/index.d.ts.map +0 -1
  299. package/dist/index.js +0 -16
  300. package/dist/index.js.map +0 -1
  301. package/dist/oauth-client.d.ts +0 -4
  302. package/dist/oauth-client.d.ts.map +0 -1
  303. package/dist/oauth-client.js +0 -3
  304. package/dist/oauth-client.js.map +0 -1
  305. package/dist/oauth-dpop.d.ts +0 -3
  306. package/dist/oauth-dpop.d.ts.map +0 -1
  307. package/dist/oauth-dpop.js +0 -3
  308. package/dist/oauth-dpop.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../../src/lib/http/request.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\n// eslint-disable-next-line import/default, import/no-named-as-default-member\nimport accept from '@hapi/accept'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { languages, mediaType } = accept\nimport {\n CookieSerializeOptions,\n parse as parseCookie,\n serialize as serializeCookie,\n} from 'cookie'\nimport forwarded from 'forwarded'\nimport createHttpError from 'http-errors'\nimport { appendHeader } from './headers.js'\nimport { UrlReference, urlMatch } from './url.js'\n\nexport function validateHeaderValue(\n req: IncomingMessage,\n name: keyof IncomingMessage['headers'],\n allowedValues: readonly (string | null)[],\n) {\n const value = req.headers[name] ?? null\n\n if (Array.isArray(value)) {\n throw createHttpError(400, `Invalid ${name} header`)\n }\n\n if (!allowedValues.includes(value)) {\n throw createHttpError(\n 400,\n value\n ? `Forbidden ${name} header \"${value}\" (expected ${allowedValues})`\n : `Missing ${name} header`,\n )\n }\n}\n\nexport function validateFetchMode(\n req: IncomingMessage,\n expectedMode: readonly (\n | null\n | 'navigate'\n | 'same-origin'\n | 'no-cors'\n | 'cors'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-mode', expectedMode)\n}\n\nexport function validateFetchDest(\n req: IncomingMessage,\n expectedDest: readonly (\n | null\n | 'document'\n | 'embed'\n | 'font'\n | 'image'\n | 'manifest'\n | 'media'\n | 'object'\n | 'report'\n | 'script'\n | 'serviceworker'\n | 'sharedworker'\n | 'style'\n | 'worker'\n | 'xslt'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-dest', expectedDest)\n}\n\nexport function validateFetchSite(\n req: IncomingMessage,\n expectedSite: readonly (\n | null\n | 'same-origin'\n | 'same-site'\n | 'cross-site'\n | 'none'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-site', expectedSite)\n}\n\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull: true,\n): URL | null\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull?: false,\n): URL\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull = false,\n) {\n // @NOTE The header name \"referer\" is actually a misspelling of the word\n // \"referrer\". https://en.wikipedia.org/wiki/HTTP_referer\n const referrer = req.headers['referer']\n const referrerUrl = referrer ? new URL(referrer) : null\n if (referrerUrl ? !urlMatch(referrerUrl, reference) : !allowNull) {\n throw createHttpError(400, `Invalid referrer ${referrer}`)\n }\n return referrerUrl\n}\n\nexport function validateOrigin(\n req: IncomingMessage,\n expectedOrigin: string,\n optional = true,\n) {\n const reqOrigin = req.headers['origin']\n if (reqOrigin ? reqOrigin !== expectedOrigin : !optional) {\n throw createHttpError(400, `Invalid origin ${reqOrigin}`)\n }\n}\n\nexport type { CookieSerializeOptions }\n\nexport function setCookie(\n res: ServerResponse,\n cookieName: string,\n value: string,\n options?: CookieSerializeOptions,\n) {\n appendHeader(res, 'Set-Cookie', serializeCookie(cookieName, value, options))\n}\n\nexport function getCookie(\n req: IncomingMessage,\n cookieName: string,\n): string | undefined {\n const cookies = parseHttpCookies(req)\n return Object.hasOwn(cookies, cookieName) ? cookies[cookieName] : undefined\n}\n\nexport function clearCookie(\n res: ServerResponse,\n cookieName: string,\n options?: Omit<CookieSerializeOptions, 'maxAge' | 'expires'>,\n) {\n setCookie(res, cookieName, '', { ...options, maxAge: 0 })\n}\n\nexport function parseHttpCookies(\n req: IncomingMessage & { cookies?: any },\n): Record<string, undefined | string> {\n req.cookies ??= req.headers['cookie']\n ? { __proto__: null, ...parseCookie(req.headers['cookie']) }\n : { __proto__: null }\n return req.cookies\n}\n\nexport type ExtractRequestMetadataOptions = {\n /**\n * A function that determines whether a given IP address is trusted. The\n * function is called with the IP addresses and its index in the list of\n * forwarded addresses (starting from 0, 0 corresponding to the ip of the\n * incoming HTTP connection, and the last item being the first proxied IP\n * address in the proxy chain, deduced from the `X-Forwarded-For` header). The\n * function should return `true` if the IP address is trusted, and `false`\n * otherwise.\n *\n * @see {@link https://www.npmjs.com/package/proxy-addr} for a utility that\n * allows you to create a trust function.\n */\n trustProxy?: (addr: string, i: number) => boolean\n}\n\nexport type RequestMetadata = {\n userAgent?: string\n ipAddress: string\n port: number\n}\n\nexport function extractRequestMetadata(\n req: IncomingMessage,\n options?: ExtractRequestMetadataOptions,\n): RequestMetadata {\n const ip = extractIp(req, options)\n return {\n userAgent: req.headers['user-agent'],\n ipAddress: ip,\n port: extractPort(req, ip),\n }\n}\n\nfunction extractIp(\n req: IncomingMessage,\n options?: ExtractRequestMetadataOptions,\n): string {\n const trust = options?.trustProxy\n if (trust) {\n const ips = forwarded(req)\n for (let i = 0; i < ips.length; i++) {\n const isTrusted = trust(ips[i], i)\n if (!isTrusted) return ips[i]\n }\n // Let's return the last (\"furthest\") IP address in the chain if all of them\n // are trusted. Note that this may indicate an issue with either the trust\n // function (too permissive), or the proxy configuration (one of them not\n // setting the X-Forwarded-For header).\n const ip = ips[ips.length - 1]\n if (ip) return ip\n }\n\n // Express app compatibility (see \"trust proxy\" setting)\n if ('ip' in req) {\n const ip = req.ip\n if (typeof ip === 'string') return ip\n }\n\n const ip = req.socket.remoteAddress\n if (ip) return ip\n\n throw new Error('Could not determine IP address')\n}\n\nfunction extractPort(req: IncomingMessage, ip: string): number {\n if (ip !== req.socket.remoteAddress) {\n // Trust the X-Forwarded-Port header only if the IP address was a trusted\n // proxied IP.\n const forwardedPort = req.headers['x-forwarded-port']\n if (typeof forwardedPort === 'string') {\n const port = Number(forwardedPort.trim())\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error('Invalid forwarded port')\n }\n return port\n }\n }\n\n const port = req.socket.remotePort\n if (port != null) return port\n\n throw new Error('Could not determine port')\n}\n\nexport function extractLocales(req: IncomingMessage) {\n const acceptLanguage = req.headers['accept-language']\n return acceptLanguage ? languages(acceptLanguage) : []\n}\n\nexport function negotiateResponseContent<T extends string>(\n req: IncomingMessage,\n types: readonly T[],\n): T | undefined {\n const type = mediaType(req.headers['accept'], types)\n if (type) return type as T\n\n return undefined\n}\n"]}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../../src/lib/http/request.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\n// eslint-disable-next-line import/default, import/no-named-as-default-member\nimport accept from '@hapi/accept'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { languages, mediaType } = accept\nimport {\n type CookieSerializeOptions,\n parse as parseCookie,\n serialize as serializeCookie,\n} from 'cookie'\nimport forwarded from 'forwarded'\nimport createHttpError from 'http-errors'\nimport { appendHeader } from './headers.js'\nimport { type UrlReference, urlMatch } from './url.js'\n\nexport function validateHeaderValue(\n req: IncomingMessage,\n name: keyof IncomingMessage['headers'],\n allowedValues: readonly (string | null)[],\n) {\n const value = req.headers[name] ?? null\n\n if (Array.isArray(value)) {\n throw createHttpError(400, `Invalid ${name} header`)\n }\n\n if (!allowedValues.includes(value)) {\n throw createHttpError(\n 400,\n value\n ? `Forbidden ${name} header \"${value}\" (expected ${allowedValues})`\n : `Missing ${name} header`,\n )\n }\n}\n\nexport function validateFetchMode(\n req: IncomingMessage,\n expectedMode: readonly (\n | null\n | 'navigate'\n | 'same-origin'\n | 'no-cors'\n | 'cors'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-mode', expectedMode)\n}\n\nexport function validateFetchDest(\n req: IncomingMessage,\n expectedDest: readonly (\n | null\n | 'document'\n | 'embed'\n | 'font'\n | 'image'\n | 'manifest'\n | 'media'\n | 'object'\n | 'report'\n | 'script'\n | 'serviceworker'\n | 'sharedworker'\n | 'style'\n | 'worker'\n | 'xslt'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-dest', expectedDest)\n}\n\nexport function validateFetchSite(\n req: IncomingMessage,\n expectedSite: readonly (\n | null\n | 'same-origin'\n | 'same-site'\n | 'cross-site'\n | 'none'\n )[],\n) {\n validateHeaderValue(req, 'sec-fetch-site', expectedSite)\n}\n\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull: true,\n): URL | null\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull?: false,\n): URL\nexport function validateReferrer(\n req: IncomingMessage,\n reference: UrlReference,\n allowNull = false,\n) {\n // @NOTE The header name \"referer\" is actually a misspelling of the word\n // \"referrer\". https://en.wikipedia.org/wiki/HTTP_referer\n const referrer = req.headers['referer']\n const referrerUrl = referrer ? new URL(referrer) : null\n if (referrerUrl ? !urlMatch(referrerUrl, reference) : !allowNull) {\n throw createHttpError(400, `Invalid referrer ${referrer}`)\n }\n return referrerUrl\n}\n\nexport function validateOrigin(\n req: IncomingMessage,\n expectedOrigin: string,\n optional = true,\n) {\n const reqOrigin = req.headers['origin']\n if (reqOrigin ? reqOrigin !== expectedOrigin : !optional) {\n throw createHttpError(400, `Invalid origin ${reqOrigin}`)\n }\n}\n\nexport type { CookieSerializeOptions }\n\nexport function setCookie(\n res: ServerResponse,\n cookieName: string,\n value: string,\n options?: CookieSerializeOptions,\n) {\n appendHeader(res, 'Set-Cookie', serializeCookie(cookieName, value, options))\n}\n\nexport function getCookie(\n req: IncomingMessage,\n cookieName: string,\n): string | undefined {\n const cookies = parseHttpCookies(req)\n return Object.hasOwn(cookies, cookieName) ? cookies[cookieName] : undefined\n}\n\nexport function clearCookie(\n res: ServerResponse,\n cookieName: string,\n options?: Omit<CookieSerializeOptions, 'maxAge' | 'expires'>,\n) {\n setCookie(res, cookieName, '', { ...options, maxAge: 0 })\n}\n\nexport function parseHttpCookies(\n req: IncomingMessage & { cookies?: any },\n): Record<string, undefined | string> {\n req.cookies ??= req.headers['cookie']\n ? { __proto__: null, ...parseCookie(req.headers['cookie']) }\n : { __proto__: null }\n return req.cookies\n}\n\nexport type ExtractRequestMetadataOptions = {\n /**\n * A function that determines whether a given IP address is trusted. The\n * function is called with the IP addresses and its index in the list of\n * forwarded addresses (starting from 0, 0 corresponding to the ip of the\n * incoming HTTP connection, and the last item being the first proxied IP\n * address in the proxy chain, deduced from the `X-Forwarded-For` header). The\n * function should return `true` if the IP address is trusted, and `false`\n * otherwise.\n *\n * @see {@link https://www.npmjs.com/package/proxy-addr} for a utility that\n * allows you to create a trust function.\n */\n trustProxy?: (addr: string, i: number) => boolean\n}\n\nexport type RequestMetadata = {\n userAgent?: string\n ipAddress: string\n port: number\n}\n\nexport function extractRequestMetadata(\n req: IncomingMessage,\n options?: ExtractRequestMetadataOptions,\n): RequestMetadata {\n const ip = extractIp(req, options)\n return {\n userAgent: req.headers['user-agent'],\n ipAddress: ip,\n port: extractPort(req, ip),\n }\n}\n\nfunction extractIp(\n req: IncomingMessage,\n options?: ExtractRequestMetadataOptions,\n): string {\n const trust = options?.trustProxy\n if (trust) {\n const ips = forwarded(req)\n for (let i = 0; i < ips.length; i++) {\n const isTrusted = trust(ips[i], i)\n if (!isTrusted) return ips[i]\n }\n // Let's return the last (\"furthest\") IP address in the chain if all of them\n // are trusted. Note that this may indicate an issue with either the trust\n // function (too permissive), or the proxy configuration (one of them not\n // setting the X-Forwarded-For header).\n const ip = ips[ips.length - 1]\n if (ip) return ip\n }\n\n // Express app compatibility (see \"trust proxy\" setting)\n if ('ip' in req) {\n const ip = req.ip\n if (typeof ip === 'string') return ip\n }\n\n const ip = req.socket.remoteAddress\n if (ip) return ip\n\n throw new Error('Could not determine IP address')\n}\n\nfunction extractPort(req: IncomingMessage, ip: string): number {\n if (ip !== req.socket.remoteAddress) {\n // Trust the X-Forwarded-Port header only if the IP address was a trusted\n // proxied IP.\n const forwardedPort = req.headers['x-forwarded-port']\n if (typeof forwardedPort === 'string') {\n const port = Number(forwardedPort.trim())\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error('Invalid forwarded port')\n }\n return port\n }\n }\n\n const port = req.socket.remotePort\n if (port != null) return port\n\n throw new Error('Could not determine port')\n}\n\nexport function extractLocales(req: IncomingMessage) {\n const acceptLanguage = req.headers['accept-language']\n return acceptLanguage ? languages(acceptLanguage) : []\n}\n\nexport function negotiateResponseContent<T extends string>(\n req: IncomingMessage,\n types: readonly T[],\n): T | undefined {\n const type = mediaType(req.headers['accept'], types)\n if (type) return type as T\n\n return undefined\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { type Readable } from 'node:stream';
3
- import { Awaitable } from '../util/type.js';
3
+ import type { Awaitable } from '../util/type.js';
4
4
  import type { Handler, Middleware } from './types.js';
5
5
  export declare function writeRedirect(res: ServerResponse, url: string, status?: number): void;
6
6
  export type WriteResponseOptions = {
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/lib/http/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,aAAa,CAAA;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAErD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,MAAM,EACX,MAAM,SAAM,GACX,IAAI,CAEN;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,QAAQ,EAChB,EACE,MAAY,EACZ,WAAwC,GACzC,GAAE,oBAAyB,GAC3B,IAAI,CAYN;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAIN;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMnD;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,OAAO,EAChB,EAAE,WAAgC,EAAE,GAAG,OAAO,EAAE,GAAE,oBAAyB,GAC1E,IAAI,CAGN;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,EAAE,WAAgC,EAAE,GAAG,OAAO,EAAE,GAAE,oBAAyB,GAC1E,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAMvE;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,oBAAoB,GAAG;IAC7D,IAAI,EAAE,CAAC,CAAA;CACR,CAAA;AAED,wBAAgB,WAAW,CACzB,CAAC,EACD,GAAG,SAAS,eAAe,GAAG,eAAe,EAC7C,GAAG,SAAS,cAAc,GAAG,cAAc,EAE3C,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC,YAAY,CAAC,GAClE,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAoBzB"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/lib/http/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAErD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,MAAM,EACX,MAAM,SAAM,GACX,IAAI,CAEN;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,QAAQ,EAChB,EACE,MAAY,EACZ,WAAwC,GACzC,GAAE,oBAAyB,GAC3B,IAAI,CAYN;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAIN;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMnD;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,OAAO,EAChB,EAAE,WAAgC,EAAE,GAAG,OAAO,EAAE,GAAE,oBAAyB,GAC1E,IAAI,CAGN;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,EAAE,WAAgC,EAAE,GAAG,OAAO,EAAE,GAAE,oBAAyB,GAC1E,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAMvE;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,oBAAoB,GAAG;IAC7D,IAAI,EAAE,CAAC,CAAA;CACR,CAAA;AAED,wBAAgB,WAAW,CACzB,CAAC,EACD,GAAG,SAAS,eAAe,GAAG,eAAe,EAC7C,GAAG,SAAS,cAAc,GAAG,cAAc,EAE3C,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC,YAAY,CAAC,GAClE,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAoBzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/lib/http/response.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,QAAQ,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,eAAe,MAAM,aAAa,CAAA;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAGvD,MAAM,UAAU,aAAa,CAC3B,GAAmB,EACnB,GAAW,EACX,MAAM,GAAG,GAAG;IAEZ,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAA;AAChD,CAAC;AAOD,MAAM,UAAU,WAAW,CACzB,GAAmB,EACnB,MAAgB,EAChB,EACE,MAAM,GAAG,GAAG,EACZ,WAAW,GAAG,0BAA0B,GACzC,GAAyB,EAAE;IAE5B,GAAG,CAAC,UAAU,GAAG,MAAM,CAAA;IACvB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IAE1C,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,GAAG,CAAC,GAAG,EAAE,CAAA;QACT,MAAM,CAAC,OAAO,EAAE,CAAA;IAClB,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,IAAkB,EAAE,EAAE;YAC7C,mDAAmD;QACrD,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,GAAmB,EACnB,KAAsB,EACtB,IAA0B;IAE1B,IAAI,IAAI,EAAE,MAAM,IAAI,IAAI;QAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAA;IACtD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,WAAW,IAAI,0BAA0B,CAAC,CAAA;IAC9E,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,GAAmB,EACnB,OAAgB,EAChB,EAAE,WAAW,GAAG,kBAAkB,EAAE,GAAG,OAAO,EAAE,GAAyB,EAAE;IAE3E,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACpC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAC,CAAA;AACvD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,EAAE,WAAW,GAAG,kBAAkB,EAAE,GAAG,OAAO,EAAE,GAAyB,EAAE;IAE3E,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,aAAa,GAAyB,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAA;IACvE,OAAO,UAAU,GAAG,EAAE,GAAG;QACvB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;IACzC,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,MAAM,GAAG,WAAW,MAAM,EAAE,CAAA;IAClC,OAAO,UAAU,GAAG,EAAE,GAAG,EAAE,IAAI;QAC7B,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QACtC,IAAI,EAAE,CAAA;IACR,CAAC,CAAA;AACH,CAAC;AAMD,MAAM,UAAU,WAAW,CAKzB,SAAmE;IAEnE,OAAO,UAAU,GAAG,EAAE,GAAG,EAAE,IAAI;QAC7B,sEAAsE;QACtE,2BAA2B;QAC3B,IAAI,wBAAwB,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;YACxD,wEAAwE;YACxE,yBAAyB;YACzB,KAAK,CAAC,KAAK,IAAI,EAAE;gBACf,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;oBACzD,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,YAAY,CAAA;oBACvD,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;gBAC9C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,+BAA+B,CAAC,CAAC,CAAA;gBACrD,CAAC;YACH,CAAC,CAAC,EAAE,CAAA;QACN,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC,CAAA;QACtD,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAAc,EAAE,OAAe;IAC9C,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;AACvE,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { type Readable, pipeline } from 'node:stream'\nimport createHttpError from 'http-errors'\nimport { Awaitable } from '../util/type.js'\nimport { negotiateResponseContent } from './request.js'\nimport type { Handler, Middleware } from './types.js'\n\nexport function writeRedirect(\n res: ServerResponse,\n url: string,\n status = 302,\n): void {\n res.writeHead(status, { Location: url }).end()\n}\n\nexport type WriteResponseOptions = {\n status?: number\n contentType?: string\n}\n\nexport function writeStream(\n res: ServerResponse,\n stream: Readable,\n {\n status = 200,\n contentType = 'application/octet-stream',\n }: WriteResponseOptions = {},\n): void {\n res.statusCode = status\n res.setHeader('content-type', contentType)\n\n if (res.req.method === 'HEAD') {\n res.end()\n stream.destroy()\n } else {\n pipeline([stream, res], (_err: Error | null) => {\n // The error will be propagated through the streams\n })\n }\n}\n\nexport function writeBuffer(\n res: ServerResponse,\n chunk: string | Buffer,\n opts: WriteResponseOptions,\n): void {\n if (opts?.status != null) res.statusCode = opts.status\n res.setHeader('content-type', opts?.contentType || 'application/octet-stream')\n res.end(chunk)\n}\n\nexport function toJsonBuffer(value: unknown): Buffer {\n try {\n return Buffer.from(JSON.stringify(value))\n } catch (cause) {\n throw new Error(`Failed to serialize as JSON`, { cause })\n }\n}\n\nexport function writeJson(\n res: ServerResponse,\n payload: unknown,\n { contentType = 'application/json', ...options }: WriteResponseOptions = {},\n): void {\n const buffer = toJsonBuffer(payload)\n writeBuffer(res, buffer, { ...options, contentType })\n}\n\nexport function staticJsonMiddleware(\n value: unknown,\n { contentType = 'application/json', ...options }: WriteResponseOptions = {},\n): Handler<unknown> {\n const buffer = toJsonBuffer(value)\n const staticOptions: WriteResponseOptions = { ...options, contentType }\n return function (req, res) {\n writeBuffer(res, buffer, staticOptions)\n }\n}\n\nexport function cacheControlMiddleware(maxAge: number): Middleware<void> {\n const header = `max-age=${maxAge}`\n return function (req, res, next) {\n res.setHeader('Cache-Control', header)\n next()\n }\n}\n\nexport type JsonResponse<P = unknown> = WriteResponseOptions & {\n json: P\n}\n\nexport function jsonHandler<\n T,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n>(\n buildJson: (this: T, req: Req, res: Res) => Awaitable<JsonResponse>,\n): Middleware<T, Req, Res> {\n return function (req, res, next) {\n // Ensure we can agree on a content encoding & type before starting to\n // build the JSON response.\n if (negotiateResponseContent(req, ['application/json'])) {\n // A middleware should not be async, so we wrap the async operation in a\n // promise and return it.\n void (async () => {\n try {\n const jsonResponse = await buildJson.call(this, req, res)\n const { json, status = 200, ...options } = jsonResponse\n writeJson(res, json, { ...options, status })\n } catch (err) {\n next(asError(err, 'Failed to build JSON response'))\n }\n })()\n } else {\n next(createHttpError(406, 'Unsupported media type'))\n }\n }\n}\n\nfunction asError(cause: unknown, message: string): Error {\n return cause instanceof Error ? cause : new Error(message, { cause })\n}\n"]}
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/lib/http/response.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { type Readable, pipeline } from 'node:stream'\nimport createHttpError from 'http-errors'\nimport type { Awaitable } from '../util/type.js'\nimport { negotiateResponseContent } from './request.js'\nimport type { Handler, Middleware } from './types.js'\n\nexport function writeRedirect(\n res: ServerResponse,\n url: string,\n status = 302,\n): void {\n res.writeHead(status, { Location: url }).end()\n}\n\nexport type WriteResponseOptions = {\n status?: number\n contentType?: string\n}\n\nexport function writeStream(\n res: ServerResponse,\n stream: Readable,\n {\n status = 200,\n contentType = 'application/octet-stream',\n }: WriteResponseOptions = {},\n): void {\n res.statusCode = status\n res.setHeader('content-type', contentType)\n\n if (res.req.method === 'HEAD') {\n res.end()\n stream.destroy()\n } else {\n pipeline([stream, res], (_err: Error | null) => {\n // The error will be propagated through the streams\n })\n }\n}\n\nexport function writeBuffer(\n res: ServerResponse,\n chunk: string | Buffer,\n opts: WriteResponseOptions,\n): void {\n if (opts?.status != null) res.statusCode = opts.status\n res.setHeader('content-type', opts?.contentType || 'application/octet-stream')\n res.end(chunk)\n}\n\nexport function toJsonBuffer(value: unknown): Buffer {\n try {\n return Buffer.from(JSON.stringify(value))\n } catch (cause) {\n throw new Error(`Failed to serialize as JSON`, { cause })\n }\n}\n\nexport function writeJson(\n res: ServerResponse,\n payload: unknown,\n { contentType = 'application/json', ...options }: WriteResponseOptions = {},\n): void {\n const buffer = toJsonBuffer(payload)\n writeBuffer(res, buffer, { ...options, contentType })\n}\n\nexport function staticJsonMiddleware(\n value: unknown,\n { contentType = 'application/json', ...options }: WriteResponseOptions = {},\n): Handler<unknown> {\n const buffer = toJsonBuffer(value)\n const staticOptions: WriteResponseOptions = { ...options, contentType }\n return function (req, res) {\n writeBuffer(res, buffer, staticOptions)\n }\n}\n\nexport function cacheControlMiddleware(maxAge: number): Middleware<void> {\n const header = `max-age=${maxAge}`\n return function (req, res, next) {\n res.setHeader('Cache-Control', header)\n next()\n }\n}\n\nexport type JsonResponse<P = unknown> = WriteResponseOptions & {\n json: P\n}\n\nexport function jsonHandler<\n T,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n>(\n buildJson: (this: T, req: Req, res: Res) => Awaitable<JsonResponse>,\n): Middleware<T, Req, Res> {\n return function (req, res, next) {\n // Ensure we can agree on a content encoding & type before starting to\n // build the JSON response.\n if (negotiateResponseContent(req, ['application/json'])) {\n // A middleware should not be async, so we wrap the async operation in a\n // promise and return it.\n void (async () => {\n try {\n const jsonResponse = await buildJson.call(this, req, res)\n const { json, status = 200, ...options } = jsonResponse\n writeJson(res, json, { ...options, status })\n } catch (err) {\n next(asError(err, 'Failed to build JSON response'))\n }\n })()\n } else {\n next(createHttpError(406, 'Unsupported media type'))\n }\n }\n}\n\nfunction asError(cause: unknown, message: string): Error {\n return cause instanceof Error ? cause : new Error(message, { cause })\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- import { SubCtx } from './context.js';
3
- import { MethodMatcherInput } from './method.js';
4
- import { Params, Path } from './path.js';
5
- import { Middleware } from './types.js';
2
+ import { type SubCtx } from './context.js';
3
+ import { type MethodMatcherInput } from './method.js';
4
+ import { type Params, type Path } from './path.js';
5
+ import type { Middleware } from './types.js';
6
6
  export type RouteCtx<T extends object | void, P extends Params = Params> = SubCtx<T, {
7
7
  params: Readonly<P>;
8
8
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/lib/http/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,MAAM,EAAU,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAuB,MAAM,aAAa,CAAA;AAErE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAqB,MAAM,WAAW,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,MAAM,QAAQ,CAClB,CAAC,SAAS,MAAM,GAAG,IAAI,EACvB,CAAC,SAAS,MAAM,GAAG,MAAM,IACvB,MAAM,CAAC,CAAC,EAAE;IAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,CAAA;AACtC,MAAM,MAAM,eAAe,CACzB,CAAC,SAAS,MAAM,GAAG,IAAI,EACvB,CAAC,SAAS,MAAM,EAChB,GAAG,GAAG,eAAe,EACrB,GAAG,GAAG,cAAc,IAClB,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAExC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,IAAI,EAC9B,GAAG,SAAS,eAAe,GAAG,eAAe,EAC7C,GAAG,SAAS,cAAc,GAAG,cAAc,EAE3C,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EACb,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GACvC,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAkBzB"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/lib/http/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,KAAK,MAAM,EAAU,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,KAAK,kBAAkB,EAAuB,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAqB,MAAM,WAAW,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,QAAQ,CAClB,CAAC,SAAS,MAAM,GAAG,IAAI,EACvB,CAAC,SAAS,MAAM,GAAG,MAAM,IACvB,MAAM,CAAC,CAAC,EAAE;IAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,CAAA;AACtC,MAAM,MAAM,eAAe,CACzB,CAAC,SAAS,MAAM,GAAG,IAAI,EACvB,CAAC,SAAS,MAAM,EAChB,GAAG,GAAG,eAAe,EACrB,GAAG,GAAG,cAAc,IAClB,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAExC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,IAAI,EAC9B,GAAG,SAAS,eAAe,GAAG,eAAe,EAC7C,GAAG,SAAS,cAAc,GAAG,cAAc,EAE3C,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EACb,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GACvC,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAkBzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../src/lib/http/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,MAAM,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAsB,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAgB,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAc3D;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAMzB,MAA0B,EAC1B,IAAa,EACb,GAAG,EAAqC;IAExC,MAAM,aAAa,GAAG,iBAAiB,CAAI,IAAI,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAEjD,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IAEnE,OAAO,UAAU,GAAG,EAAE,GAAG,EAAE,IAAI;QAC7B,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAA;YAC9C,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;gBACxC,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;YACjD,CAAC;QACH,CAAC;QAED,OAAO,IAAI,EAAE,CAAA;IACf,CAAC,CAAA;AACH,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { SubCtx, subCtx } from './context.js'\nimport { MethodMatcherInput, createMethodMatcher } from './method.js'\nimport { combineMiddlewares } from './middleware.js'\nimport { Params, Path, createPathMatcher } from './path.js'\nimport { Middleware } from './types.js'\n\nexport type RouteCtx<\n T extends object | void,\n P extends Params = Params,\n> = SubCtx<T, { params: Readonly<P> }>\nexport type RouteMiddleware<\n T extends object | void,\n P extends Params,\n Req = IncomingMessage,\n Res = ServerResponse,\n> = Middleware<RouteCtx<T, P>, Req, Res>\n\n/**\n * @example\n * ```ts\n * createRoute<{ foo: string }>('GET', '/foo/:foo', function (req, res) {\n * console.log(this.params.foo) // OK\n * console.log(this.params.bar) // Error\n * })\n *\n * createRoute<{ foo: string }>(['POST', 'PUT'], '/foo/:foo', function (req, res) {\n * console.log(this.params.foo) // OK\n * console.log(this.params.bar) // Error\n * })\n * ```\n */\nexport function createRoute<\n P extends Params = Params,\n T extends object | void = void,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n>(\n method: MethodMatcherInput,\n path: Path<P>,\n ...mw: RouteMiddleware<T, P, Req, Res>[]\n): Middleware<T, Req, Res> {\n const paramsMatcher = createPathMatcher<P>(path)\n const methodMatcher = createMethodMatcher(method)\n\n const middleware = combineMiddlewares(mw, { skipKeyword: 'route' })\n\n return function (req, res, next) {\n if (methodMatcher(req)) {\n const pathname = req.url?.split('?')[0] ?? '/'\n const params = paramsMatcher(pathname)\n if (params) {\n const context = subCtx(this, { params })\n return middleware.call(context, req, res, next)\n }\n }\n\n return next()\n }\n}\n"]}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../src/lib/http/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,MAAM,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAA2B,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAA0B,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAcrE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAMzB,MAA0B,EAC1B,IAAa,EACb,GAAG,EAAqC;IAExC,MAAM,aAAa,GAAG,iBAAiB,CAAI,IAAI,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAEjD,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IAEnE,OAAO,UAAU,GAAG,EAAE,GAAG,EAAE,IAAI;QAC7B,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAA;YAC9C,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;YACtC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;gBACxC,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;YACjD,CAAC;QACH,CAAC;QAED,OAAO,IAAI,EAAE,CAAA;IACf,CAAC,CAAA;AACH,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { type SubCtx, subCtx } from './context.js'\nimport { type MethodMatcherInput, createMethodMatcher } from './method.js'\nimport { combineMiddlewares } from './middleware.js'\nimport { type Params, type Path, createPathMatcher } from './path.js'\nimport type { Middleware } from './types.js'\n\nexport type RouteCtx<\n T extends object | void,\n P extends Params = Params,\n> = SubCtx<T, { params: Readonly<P> }>\nexport type RouteMiddleware<\n T extends object | void,\n P extends Params,\n Req = IncomingMessage,\n Res = ServerResponse,\n> = Middleware<RouteCtx<T, P>, Req, Res>\n\n/**\n * @example\n * ```ts\n * createRoute<{ foo: string }>('GET', '/foo/:foo', function (req, res) {\n * console.log(this.params.foo) // OK\n * console.log(this.params.bar) // Error\n * })\n *\n * createRoute<{ foo: string }>(['POST', 'PUT'], '/foo/:foo', function (req, res) {\n * console.log(this.params.foo) // OK\n * console.log(this.params.bar) // Error\n * })\n * ```\n */\nexport function createRoute<\n P extends Params = Params,\n T extends object | void = void,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n>(\n method: MethodMatcherInput,\n path: Path<P>,\n ...mw: RouteMiddleware<T, P, Req, Res>[]\n): Middleware<T, Req, Res> {\n const paramsMatcher = createPathMatcher<P>(path)\n const methodMatcher = createMethodMatcher(method)\n\n const middleware = combineMiddlewares(mw, { skipKeyword: 'route' })\n\n return function (req, res, next) {\n if (methodMatcher(req)) {\n const pathname = req.url?.split('?')[0] ?? '/'\n const params = paramsMatcher(pathname)\n if (params) {\n const context = subCtx(this, { params })\n return middleware.call(context, req, res, next)\n }\n }\n\n return next()\n }\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
2
- import { SubCtx } from './context.js';
3
- import { MethodMatcherInput } from './method.js';
4
- import { Params, Path } from './path.js';
5
- import { RouteMiddleware } from './route.js';
6
- import { Middleware } from './types.js';
2
+ import { type SubCtx } from './context.js';
3
+ import type { MethodMatcherInput } from './method.js';
4
+ import type { Params, Path } from './path.js';
5
+ import { type RouteMiddleware } from './route.js';
6
+ import type { Middleware } from './types.js';
7
7
  export type RouterCtx<T extends object | void = void> = SubCtx<T, {
8
8
  url: Readonly<URL>;
9
9
  headers: IncomingHttpHeaders;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/lib/http/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/lib/http/router.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/lib/http/router.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IncomingHttpHeaders,\n IncomingMessage,\n ServerResponse,\n} from 'node:http'\nimport { SubCtx, subCtx } from './context.js'\nimport { MethodMatcherInput } from './method.js'\nimport { combineMiddlewares } from './middleware.js'\nimport { Params, Path } from './path.js'\nimport { RouteMiddleware, createRoute } from './route.js'\nimport { Middleware } from './types.js'\n\nexport type RouterCtx<T extends object | void = void> = SubCtx<\n T,\n { url: Readonly<URL>; headers: IncomingHttpHeaders }\n>\n\nexport type RouterMiddleware<\n T extends object | void = void,\n Req = IncomingMessage,\n Res = ServerResponse,\n> = Middleware<RouterCtx<T>, Req, Res>\n\nexport type RouterConfig = {\n /** Used to build the origin of the {@link RouterCtx['url']} context property */\n protocol?: string\n /** Used to build the origin of the {@link RouterCtx['url']} context property */\n host?: string\n}\n\nexport class Router<\n T extends object | void = void,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n> {\n private readonly middlewares: RouterMiddleware<T, Req, Res>[] = []\n\n constructor(private readonly config?: RouterConfig) {}\n\n use(...middlewares: RouterMiddleware<T, Req, Res>[]) {\n this.middlewares.push(...middlewares)\n return this\n }\n\n all<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('*', path, ...mw)\n }\n\n get<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('GET', path, ...mw)\n }\n\n post<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('POST', path, ...mw)\n }\n\n options<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('OPTIONS', path, ...mw)\n }\n\n addRoute<P extends Params>(\n method: MethodMatcherInput,\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.use(createRoute(method, path, ...mw))\n }\n\n /**\n * @returns router middleware which dispatches a route matching the request.\n */\n buildMiddleware(): Middleware<T, Req, Res> {\n const { config } = this\n\n // Calling next('router') from a middleware will skip all the remaining\n // middlewares in the stack.\n const middleware = combineMiddlewares(this.middlewares, {\n skipKeyword: 'router',\n })\n\n return function (this, req, res, next) {\n // Parse the URL using node's URL parser.\n const url = extractUrl(req, config)\n if (url instanceof Error) return next(url)\n\n // Any error thrown here will be uncaught/unhandled (a middleware should\n // never throw)\n const context = subCtx(this, { url, headers: req.headers })\n middleware.call(context, req, res, next)\n }\n }\n}\n\nfunction extractUrl(req: IncomingMessage, config?: RouterConfig): URL | Error {\n try {\n const protocol = config?.protocol || 'https:'\n const host = config?.host || req.headers.host || 'localhost'\n const pathname = req.url || '/'\n return new URL(pathname, `${protocol}//${host}`)\n } catch (cause) {\n const error =\n cause instanceof Error ? cause : new Error('Invalid URL', { cause })\n return Object.assign(error, { status: 400, statusCode: 400 })\n }\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/lib/http/router.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IncomingHttpHeaders,\n IncomingMessage,\n ServerResponse,\n} from 'node:http'\nimport { type SubCtx, subCtx } from './context.js'\nimport type { MethodMatcherInput } from './method.js'\nimport { combineMiddlewares } from './middleware.js'\nimport type { Params, Path } from './path.js'\nimport { type RouteMiddleware, createRoute } from './route.js'\nimport type { Middleware } from './types.js'\n\nexport type RouterCtx<T extends object | void = void> = SubCtx<\n T,\n { url: Readonly<URL>; headers: IncomingHttpHeaders }\n>\n\nexport type RouterMiddleware<\n T extends object | void = void,\n Req = IncomingMessage,\n Res = ServerResponse,\n> = Middleware<RouterCtx<T>, Req, Res>\n\nexport type RouterConfig = {\n /** Used to build the origin of the {@link RouterCtx['url']} context property */\n protocol?: string\n /** Used to build the origin of the {@link RouterCtx['url']} context property */\n host?: string\n}\n\nexport class Router<\n T extends object | void = void,\n Req extends IncomingMessage = IncomingMessage,\n Res extends ServerResponse = ServerResponse,\n> {\n private readonly middlewares: RouterMiddleware<T, Req, Res>[] = []\n\n constructor(private readonly config?: RouterConfig) {}\n\n use(...middlewares: RouterMiddleware<T, Req, Res>[]) {\n this.middlewares.push(...middlewares)\n return this\n }\n\n all<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('*', path, ...mw)\n }\n\n get<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('GET', path, ...mw)\n }\n\n post<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('POST', path, ...mw)\n }\n\n options<P extends Params = Params>(\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.addRoute<P>('OPTIONS', path, ...mw)\n }\n\n addRoute<P extends Params>(\n method: MethodMatcherInput,\n path: Path<P>,\n ...mw: RouteMiddleware<RouterCtx<T>, P, Req, Res>[]\n ) {\n return this.use(createRoute(method, path, ...mw))\n }\n\n /**\n * @returns router middleware which dispatches a route matching the request.\n */\n buildMiddleware(): Middleware<T, Req, Res> {\n const { config } = this\n\n // Calling next('router') from a middleware will skip all the remaining\n // middlewares in the stack.\n const middleware = combineMiddlewares(this.middlewares, {\n skipKeyword: 'router',\n })\n\n return function (this, req, res, next) {\n // Parse the URL using node's URL parser.\n const url = extractUrl(req, config)\n if (url instanceof Error) return next(url)\n\n // Any error thrown here will be uncaught/unhandled (a middleware should\n // never throw)\n const context = subCtx(this, { url, headers: req.headers })\n middleware.call(context, req, res, next)\n }\n }\n}\n\nfunction extractUrl(req: IncomingMessage, config?: RouterConfig): URL | Error {\n try {\n const protocol = config?.protocol || 'https:'\n const host = config?.host || req.headers.host || 'localhost'\n const pathname = req.url || '/'\n return new URL(pathname, `${protocol}//${host}`)\n } catch (cause) {\n const error =\n cause instanceof Error ? cause : new Error('Invalid URL', { cause })\n return Object.assign(error, { status: 400, statusCode: 400 })\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
- import { Readable } from 'node:stream';
3
- import { KnownNames, ParserResult } from './parser.js';
2
+ import type { Readable } from 'node:stream';
3
+ import { type KnownNames, type ParserResult } from './parser.js';
4
4
  export declare function decodeHttpRequest(req: IncomingMessage): Readable;
5
5
  /**
6
6
  * Generic method that parses a stream of unknown nature (HTTP request/response,
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/lib/http/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGtC,OAAO,EACL,UAAU,EAEV,YAAY,EAGb,MAAM,aAAa,CAAA;AAEpB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,QAAQ,CAQhE;AAED;;;;;GAKG;AAEH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,SAAS,UAAU,EAAE,EACpE,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,CAAC;;;;;UAiBuB,CAAC,CAAC,MAAM,CAAC;;;;;;;;;;;;;KAEzC;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/lib/http/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAA;AAEpB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,QAAQ,CAQhE;AAED;;;;;GAKG;AAEH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,SAAS,UAAU,EAAE,EACpE,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,CAAC;;;;;UAiBuB,CAAC,CAAC,MAAM,CAAC;;;;;;;;;;;;;KAEzC;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../src/lib/http/stream.ts"],"names":[],"mappings":"AAEA,OAAO,eAAe,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAIL,gBAAgB,EAChB,OAAO,GACR,MAAM,aAAa,CAAA;AAEpB,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GACX,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAA;QACzE,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAChD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AAEH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAoB,EACpB,KAAQ;IAER,MAAM,IAAI,GAAG,gBAAgB,CAC3B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,0BAA0B,CAC1D,CAAA;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAClE,CAAA;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,eAAe,CAAC,GAAG,EAAE,6BAA6B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC/C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAE/B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAA0B;IAC1D,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QAC7B,mCAAmC;IACrC,CAAC;AACH,CAAC","sourcesContent":["import type { IncomingMessage } from 'node:http'\nimport { Readable } from 'node:stream'\nimport createHttpError from 'http-errors'\nimport { decodeStream, streamToNodeBuffer } from '@atproto/common'\nimport {\n KnownNames,\n KnownParser,\n ParserResult,\n parseContentType,\n parsers,\n} from './parser.js'\n\nexport function decodeHttpRequest(req: IncomingMessage): Readable {\n try {\n return decodeStream(req, req.headers['content-encoding'])\n } catch (cause) {\n const message =\n cause instanceof TypeError ? cause.message : `Invalid content-encoding`\n throw createHttpError(415, message, { cause })\n }\n}\n\n/**\n * Generic method that parses a stream of unknown nature (HTTP request/response,\n * socket, file, etc.), but of known mime type, into a parsed object.\n *\n * @throws {TypeError} If the content-type is not valid or supported.\n */\n\nexport async function parseHttpRequest<A extends readonly KnownNames[]>(\n req: IncomingMessage,\n allow: A,\n) {\n const type = parseContentType(\n req.headers['content-type'] ?? 'application/octet-stream',\n )\n\n const parser = parsers.find(\n (parser) => allow.includes(parser.name) && parser.test(type.mime),\n )\n\n if (!parser) {\n throw createHttpError(415, `Unsupported content-type: ${type.mime}`)\n }\n\n const stream = decodeHttpRequest(req)\n const buffer = await streamToNodeBuffer(stream)\n return parser.parse(buffer, type) as ParserResult<\n Extract<KnownParser, { name: A[number] }>\n >\n}\n\nexport async function flushStream(stream: AsyncIterable<any>): Promise<void> {\n for await (const _ of stream) {\n // Consume the stream to completion\n }\n}\n"]}
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../src/lib/http/stream.ts"],"names":[],"mappings":"AAEA,OAAO,eAAe,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAIL,gBAAgB,EAChB,OAAO,GACR,MAAM,aAAa,CAAA;AAEpB,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GACX,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAA;QACzE,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAChD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AAEH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAoB,EACpB,KAAQ;IAER,MAAM,IAAI,GAAG,gBAAgB,CAC3B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,0BAA0B,CAC1D,CAAA;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAClE,CAAA;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,eAAe,CAAC,GAAG,EAAE,6BAA6B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC/C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAE/B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAA0B;IAC1D,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QAC7B,mCAAmC;IACrC,CAAC;AACH,CAAC","sourcesContent":["import type { IncomingMessage } from 'node:http'\nimport type { Readable } from 'node:stream'\nimport createHttpError from 'http-errors'\nimport { decodeStream, streamToNodeBuffer } from '@atproto/common'\nimport {\n type KnownNames,\n type KnownParser,\n type ParserResult,\n parseContentType,\n parsers,\n} from './parser.js'\n\nexport function decodeHttpRequest(req: IncomingMessage): Readable {\n try {\n return decodeStream(req, req.headers['content-encoding'])\n } catch (cause) {\n const message =\n cause instanceof TypeError ? cause.message : `Invalid content-encoding`\n throw createHttpError(415, message, { cause })\n }\n}\n\n/**\n * Generic method that parses a stream of unknown nature (HTTP request/response,\n * socket, file, etc.), but of known mime type, into a parsed object.\n *\n * @throws {TypeError} If the content-type is not valid or supported.\n */\n\nexport async function parseHttpRequest<A extends readonly KnownNames[]>(\n req: IncomingMessage,\n allow: A,\n) {\n const type = parseContentType(\n req.headers['content-type'] ?? 'application/octet-stream',\n )\n\n const parser = parsers.find(\n (parser) => allow.includes(parser.name) && parser.test(type.mime),\n )\n\n if (!parser) {\n throw createHttpError(415, `Unsupported content-type: ${type.mime}`)\n }\n\n const stream = decodeHttpRequest(req)\n const buffer = await streamToNodeBuffer(stream)\n return parser.parse(buffer, type) as ParserResult<\n Extract<KnownParser, { name: A[number] }>\n >\n}\n\nexport async function flushStream(stream: AsyncIterable<any>): Promise<void> {\n for await (const _ of stream) {\n // Consume the stream to completion\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Awaitable } from './type.js';
1
+ import type { Awaitable } from './type.js';
2
2
  export declare function onOvertimeDefault(options: {
3
3
  start: number;
4
4
  end: number;
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,IAAI,CAIP;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,EACtB,UAAU,2BAAoB,GAC7B,OAAO,CAAC,CAAC,CAAC,CA2BZ"}
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,IAAI,CAIP;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,EACtB,UAAU,2BAAoB,GAC7B,OAAO,CAAC,CAAC,CAAC,CA2BZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAG1D,MAAM,UAAU,iBAAiB,CAAC,OAKjC;IACC,OAAO,CAAC,IAAI,CACV,oCAAoC,OAAO,CAAC,OAAO,6BAA6B,OAAO,CAAC,IAAI,gFAAgF,CAC7K,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,EAAsB,EACtB,UAAU,GAAG,iBAAiB;IAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAA;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,OAAO,GAAG,GAAG,GAAG,KAAK,CAAA;QAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,CAAA;QAChC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAEzC,iEAAiE;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;YAC5C,MAAM,SAAS,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAA;YAE7C,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { Awaitable } from './type.js'\n\nexport function onOvertimeDefault(options: {\n start: number\n end: number\n elapsed: number\n time: number\n}): void {\n console.warn(\n `constantTime: execution time was ${options.elapsed}ms (which is greater than ${options.time}ms). You should increase the \"time\" to properly defend against timing attacks.`,\n )\n}\n\n/**\n * Utility function to protect against timing attacks.\n */\nexport async function constantTime<R>(\n time: number,\n fn: () => Awaitable<R>,\n onOvertime = onOvertimeDefault,\n): Promise<R> {\n if (!Number.isFinite(time) || time <= 0) {\n throw new TypeError(`\"time\" must be a positive number`)\n }\n\n const start = Date.now()\n try {\n return await fn()\n } finally {\n const end = Date.now()\n const elapsed = end - start\n\n const remaining = time - elapsed\n if (remaining >= 0) {\n // Happy path, execution time was smaller than \"time\"\n await sleep(remaining)\n } else {\n // The function execution took longer than \"time\"\n onOvertime({ start, end, elapsed, time })\n\n // Sleep until the next multiple of \"time\" to mitigate any attack\n const multiplier = Math.ceil(elapsed / time)\n const remaining = multiplier * time - elapsed\n\n await sleep(remaining)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/lib/util/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAG1D,MAAM,UAAU,iBAAiB,CAAC,OAKjC;IACC,OAAO,CAAC,IAAI,CACV,oCAAoC,OAAO,CAAC,OAAO,6BAA6B,OAAO,CAAC,IAAI,gFAAgF,CAC7K,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,EAAsB,EACtB,UAAU,GAAG,iBAAiB;IAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAA;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,OAAO,GAAG,GAAG,GAAG,KAAK,CAAA;QAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,CAAA;QAChC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAEzC,iEAAiE;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;YAC5C,MAAM,SAAS,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAA;YAE7C,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport type { Awaitable } from './type.js'\n\nexport function onOvertimeDefault(options: {\n start: number\n end: number\n elapsed: number\n time: number\n}): void {\n console.warn(\n `constantTime: execution time was ${options.elapsed}ms (which is greater than ${options.time}ms). You should increase the \"time\" to properly defend against timing attacks.`,\n )\n}\n\n/**\n * Utility function to protect against timing attacks.\n */\nexport async function constantTime<R>(\n time: number,\n fn: () => Awaitable<R>,\n onOvertime = onOvertimeDefault,\n): Promise<R> {\n if (!Number.isFinite(time) || time <= 0) {\n throw new TypeError(`\"time\" must be a positive number`)\n }\n\n const start = Date.now()\n try {\n return await fn()\n } finally {\n const end = Date.now()\n const elapsed = end - start\n\n const remaining = time - elapsed\n if (remaining >= 0) {\n // Happy path, execution time was smaller than \"time\"\n await sleep(remaining)\n } else {\n // The function execution took longer than \"time\"\n onOvertime({ start, end, elapsed, time })\n\n // Sleep until the next multiple of \"time\" to mitigate any attack\n const multiplier = Math.ceil(elapsed / time)\n const remaining = multiplier * time - elapsed\n\n await sleep(remaining)\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { ZodError, ZodIssue } from 'zod';
1
+ import { type ZodError, type ZodIssue } from 'zod';
2
2
  export declare function formatZodError(err: ZodError, prefix?: string): string;
3
3
  export declare function formatZodIssue(issue: ZodIssue): string;
4
4
  //# sourceMappingURL=zod-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zod-error.d.ts","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAgB,MAAM,KAAK,CAAA;AAEtD,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAgBtD"}
1
+ {"version":3,"file":"zod-error.d.ts","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAgB,MAAM,KAAK,CAAA;AAEhE,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAgBtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"zod-error.js","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,KAAK,CAAA;AAEtD,MAAM,UAAU,cAAc,CAAC,GAAa,EAAE,MAAe;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM;QAC/B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA,CAAC,qDAAqD;IACrE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,aAAa,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,WAAW;aACrB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,GAAG,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,GAAG,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC","sourcesContent":["import { ZodError, ZodIssue, ZodIssueCode } from 'zod'\n\nexport function formatZodError(err: ZodError, prefix?: string): string {\n const message = err.issues.length\n ? err.issues.map(formatZodIssue).join('; ')\n : err.message // Should never happen (issues should never be empty)\n return prefix ? `${prefix}: ${message}` : message\n}\n\nexport function formatZodIssue(issue: ZodIssue): string {\n if (issue.code === ZodIssueCode.invalid_union) {\n return issue.unionErrors\n .map((err) => err.issues.map(formatZodIssue).join('; '))\n .join(', or ')\n }\n\n if (issue.path.length === 1 && typeof issue.path[0] === 'number') {\n return `${issue.message} at index ${issue.path[0]}`\n }\n\n if (issue.path.length) {\n return `${issue.message} at ${issue.path.join('.')}`\n }\n\n return issue.message\n}\n"]}
1
+ {"version":3,"file":"zod-error.js","sourceRoot":"","sources":["../../../src/lib/util/zod-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,YAAY,EAAE,MAAM,KAAK,CAAA;AAEhE,MAAM,UAAU,cAAc,CAAC,GAAa,EAAE,MAAe;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM;QAC/B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA,CAAC,qDAAqD;IACrE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,aAAa,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,WAAW;aACrB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,GAAG,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,GAAG,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC","sourcesContent":["import { type ZodError, type ZodIssue, ZodIssueCode } from 'zod'\n\nexport function formatZodError(err: ZodError, prefix?: string): string {\n const message = err.issues.length\n ? err.issues.map(formatZodIssue).join('; ')\n : err.message // Should never happen (issues should never be empty)\n return prefix ? `${prefix}: ${message}` : message\n}\n\nexport function formatZodIssue(issue: ZodIssue): string {\n if (issue.code === ZodIssueCode.invalid_union) {\n return issue.unionErrors\n .map((err) => err.issues.map(formatZodIssue).join('; '))\n .join(', or ')\n }\n\n if (issue.path.length === 1 && typeof issue.path[0] === 'number') {\n return `${issue.message} at index ${issue.path[0]}`\n }\n\n if (issue.path.length) {\n return `${issue.message} at ${issue.path.join('.')}`\n }\n\n return issue.message\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ServerResponse } from 'node:http';
2
- import { SecurityHeadersOptions } from './http/security-headers.js';
2
+ import type { SecurityHeadersOptions } from './http/security-headers.js';
3
3
  export type WriteFormRedirectOptions = SecurityHeadersOptions;
4
4
  export declare function writeFormRedirect(res: ServerResponse, method: 'post' | 'get', uri: string, params: Iterable<[string, string]>, options?: WriteFormRedirectOptions): void;
5
5
  //# sourceMappingURL=write-form-redirect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-form-redirect.d.ts","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAG/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAGnE,MAAM,MAAM,wBAAwB,GAAG,sBAAsB,CAAA;AAyB7D,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,wBAAwB,GACjC,IAAI,CAoBN"}
1
+ {"version":3,"file":"write-form-redirect.d.ts","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAG/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAGxE,MAAM,MAAM,wBAAwB,GAAG,sBAAsB,CAAA;AAyB7D,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,wBAAwB,GACjC,IAAI,CAoBN"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-form-redirect.js","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAI3C,gFAAgF;AAChF,wEAAwE;AACxE,MAAM,MAAM,GAAG,EAAE,CAAA;;;;;;;;;;;;;;;;CAgBhB,CAAA;AAED,8EAA8E;AAC9E,gBAAgB;AAEhB,MAAM,UAAU,iBAAiB,CAC/B,GAAmB,EACnB,MAAsB,EACtB,GAAW,EACX,MAAkC,EAClC,OAAkC;IAElC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAE1C,4CAA4C;IAC5C,uGAAuG;IACvG,SAAS,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAEtE,OAAO,SAAS,CAAC,GAAG,EAAE;QACpB,GAAG,OAAO;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,IAAI,CAAA;sBACQ,MAAM,aAAa,GAAG;UAClC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAA,8BAA8B,GAAG,YAAY,KAAK,MAAM;SAC7D,CAAC;;;KAGL;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { ServerResponse } from 'node:http'\nimport { html, js } from './html/index.js'\nimport { setCookie } from './http/request.js'\nimport { SecurityHeadersOptions } from './http/security-headers.js'\nimport { writeHtml } from './write-html.js'\n\nexport type WriteFormRedirectOptions = SecurityHeadersOptions\n\n// We prevent the user from coming \"back\" to this page and resubmitting the form\n// repeatedly by disabling the submit button after the first submission.\nconst SCRIPT = js`\nconst form = document.forms[0];\n\nlet canSubmit = true;\n\nform.addEventListener('submit', (event) => {\n if (!canSubmit) {\n event.preventDefault();\n } else {\n canSubmit = false;\n }\n});\n\nsetTimeout(() => {\n form.submit();\n}, 1);\n`\n\n// @NOTE If translations and design are needed, consider replacing this with a\n// web app page.\n\nexport function writeFormRedirect(\n res: ServerResponse,\n method: 'post' | 'get',\n uri: string,\n params: Iterable<[string, string]>,\n options?: WriteFormRedirectOptions,\n): void {\n res.setHeader('Cache-Control', 'no-store')\n\n // Prevent the Chrome from caching this page\n // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/\n setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' })\n\n return writeHtml(res, {\n ...options,\n htmlAttrs: { lang: 'en' },\n scripts: [SCRIPT],\n body: html`\n <form method=\"${method}\" action=\"${uri}\">\n ${Array.from(params, ([key, value]) => [\n html`<input type=\"hidden\" name=\"${key}\" value=\"${value}\" />`,\n ])}\n <input type=\"submit\" value=\"Continue\" />\n </form>\n `,\n })\n}\n"]}
1
+ {"version":3,"file":"write-form-redirect.js","sourceRoot":"","sources":["../../src/lib/write-form-redirect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAI3C,gFAAgF;AAChF,wEAAwE;AACxE,MAAM,MAAM,GAAG,EAAE,CAAA;;;;;;;;;;;;;;;;CAgBhB,CAAA;AAED,8EAA8E;AAC9E,gBAAgB;AAEhB,MAAM,UAAU,iBAAiB,CAC/B,GAAmB,EACnB,MAAsB,EACtB,GAAW,EACX,MAAkC,EAClC,OAAkC;IAElC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAE1C,4CAA4C;IAC5C,uGAAuG;IACvG,SAAS,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;IAEtE,OAAO,SAAS,CAAC,GAAG,EAAE;QACpB,GAAG,OAAO;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,IAAI,CAAA;sBACQ,MAAM,aAAa,GAAG;UAClC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAA,8BAA8B,GAAG,YAAY,KAAK,MAAM;SAC7D,CAAC;;;KAGL;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { ServerResponse } from 'node:http'\nimport { html, js } from './html/index.js'\nimport { setCookie } from './http/request.js'\nimport type { SecurityHeadersOptions } from './http/security-headers.js'\nimport { writeHtml } from './write-html.js'\n\nexport type WriteFormRedirectOptions = SecurityHeadersOptions\n\n// We prevent the user from coming \"back\" to this page and resubmitting the form\n// repeatedly by disabling the submit button after the first submission.\nconst SCRIPT = js`\nconst form = document.forms[0];\n\nlet canSubmit = true;\n\nform.addEventListener('submit', (event) => {\n if (!canSubmit) {\n event.preventDefault();\n } else {\n canSubmit = false;\n }\n});\n\nsetTimeout(() => {\n form.submit();\n}, 1);\n`\n\n// @NOTE If translations and design are needed, consider replacing this with a\n// web app page.\n\nexport function writeFormRedirect(\n res: ServerResponse,\n method: 'post' | 'get',\n uri: string,\n params: Iterable<[string, string]>,\n options?: WriteFormRedirectOptions,\n): void {\n res.setHeader('Cache-Control', 'no-store')\n\n // Prevent the Chrome from caching this page\n // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/\n setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' })\n\n return writeHtml(res, {\n ...options,\n htmlAttrs: { lang: 'en' },\n scripts: [SCRIPT],\n body: html`\n <form method=\"${method}\" action=\"${uri}\">\n ${Array.from(params, ([key, value]) => [\n html`<input type=\"hidden\" name=\"${key}\" value=\"${value}\" />`,\n ])}\n <input type=\"submit\" value=\"Continue\" />\n </form>\n `,\n })\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { ServerResponse } from 'node:http';
2
- import { BuildDocumentOptions } from './html/index.js';
3
- import { WriteResponseOptions } from './http/response.js';
4
- import { SecurityHeadersOptions } from './http/security-headers.js';
2
+ import { type BuildDocumentOptions } from './html/index.js';
3
+ import { type WriteResponseOptions } from './http/response.js';
4
+ import { type SecurityHeadersOptions } from './http/security-headers.js';
5
5
  export type WriteHtmlOptions = BuildDocumentOptions & WriteResponseOptions & SecurityHeadersOptions;
6
6
  export declare function writeHtml(res: ServerResponse, options: WriteHtmlOptions): void;
7
7
  //# sourceMappingURL=write-html.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-html.d.ts","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,OAAO,EAEL,oBAAoB,EAGrB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,oBAAoB,EAAe,MAAM,oBAAoB,CAAA;AACtE,OAAO,EACL,sBAAsB,EAEvB,MAAM,4BAA4B,CAAA;AAEnC,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GACjD,oBAAoB,GACpB,sBAAsB,CAAA;AAExB,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CA6BN"}
1
+ {"version":3,"file":"write-html.d.ts","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,KAAK,oBAAoB,EAAe,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,4BAA4B,CAAA;AAEnC,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GACjD,oBAAoB,GACpB,sBAAsB,CAAA;AAExB,wBAAgB,SAAS,CACvB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CA6BN"}
@@ -1 +1 @@
1
- {"version":3,"file":"write-html.js","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAY,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAGL,IAAI,EACJ,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAwB,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAEL,kBAAkB,GACnB,MAAM,4BAA4B,CAAA;AAMnC,MAAM,UAAU,SAAS,CACvB,GAAmB,EACnB,OAAyB;IAEzB,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,QAAQ,CAClB;QACE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,2BAA2B,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;QACnD,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACvE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;KACtE,EACD,OAAO,CAAC,GAAG,CACZ,CAAA;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9C,oEAAoE;IACpE,kBAAkB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE;QACrB,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,0BAA0B;KAChE,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB;IACzC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,4CAA4C;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;QACjC,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;IAC5C,CAAC;SAAM,CAAC;QACN,iDAAiD;QACjD,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAA8C,CAAA;QAC1E,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC","sourcesContent":["import { createHash } from 'node:crypto'\nimport type { ServerResponse } from 'node:http'\nimport { CspValue, mergeCsp } from './csp/index.js'\nimport {\n AssetRef,\n BuildDocumentOptions,\n Html,\n buildDocument,\n} from './html/index.js'\nimport { WriteResponseOptions, writeBuffer } from './http/response.js'\nimport {\n SecurityHeadersOptions,\n setSecurityHeaders,\n} from './http/security-headers.js'\n\nexport type WriteHtmlOptions = BuildDocumentOptions &\n WriteResponseOptions &\n SecurityHeadersOptions\n\nexport function writeHtml(\n res: ServerResponse,\n options: WriteHtmlOptions,\n): void {\n // @NOTE the csp string might be quite long. In that case it might be tempting\n // to set it through the http-equiv <meta> in the HTML. However, some\n // directives cannot be enforced by browsers when set through the meta tag\n // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the\n // HTTP header.\n const csp = mergeCsp(\n {\n // Keep \"upgrade-insecure-requests\" in sync with HSTS setting. HSTS is\n // typically set to false for localhost endpoints. Chrome and FF will\n // ignore \"upgrade-insecure-requests\" from localhost, but Safari will\n // enforce it, requiring to be explicitly disable it for localhost.\n 'upgrade-insecure-requests': options.hsts !== false,\n 'default-src': [\"'none'\"],\n 'base-uri': options.base?.origin as undefined | `https://${string}`,\n 'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),\n 'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),\n },\n options.csp,\n )\n\n const html = buildDocument(options).toString()\n\n // HTML pages should always be served with safety protection headers\n setSecurityHeaders(res, { ...options, csp })\n writeBuffer(res, html, {\n ...options,\n contentType: options?.contentType ?? 'text/html; charset=utf-8',\n })\n}\n\nfunction assetToCsp(asset?: Html | AssetRef): undefined | CspValue {\n if (asset == null) return undefined\n if (asset instanceof Html) {\n // Inline assets are \"allowed\" by their hash\n const hash = createHash('sha256')\n for (const fragment of asset) hash.update(fragment)\n return `'sha256-${hash.digest('base64')}'`\n } else {\n // External assets are referenced by their origin\n if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {\n return new URL(asset.url).origin as `https:${string}` | `http:${string}`\n }\n\n // Internal assets are served from the same origin\n return `'self'`\n }\n}\n"]}
1
+ {"version":3,"file":"write-html.js","sourceRoot":"","sources":["../../src/lib/write-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAiB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAGL,IAAI,EACJ,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAA6B,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EAEL,kBAAkB,GACnB,MAAM,4BAA4B,CAAA;AAMnC,MAAM,UAAU,SAAS,CACvB,GAAmB,EACnB,OAAyB;IAEzB,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,QAAQ,CAClB;QACE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,2BAA2B,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;QACnD,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACvE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;KACtE,EACD,OAAO,CAAC,GAAG,CACZ,CAAA;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9C,oEAAoE;IACpE,kBAAkB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE;QACrB,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,0BAA0B;KAChE,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB;IACzC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,4CAA4C;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;QACjC,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;IAC5C,CAAC;SAAM,CAAC;QACN,iDAAiD;QACjD,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAA8C,CAAA;QAC1E,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC","sourcesContent":["import { createHash } from 'node:crypto'\nimport type { ServerResponse } from 'node:http'\nimport { type CspValue, mergeCsp } from './csp/index.js'\nimport {\n type AssetRef,\n type BuildDocumentOptions,\n Html,\n buildDocument,\n} from './html/index.js'\nimport { type WriteResponseOptions, writeBuffer } from './http/response.js'\nimport {\n type SecurityHeadersOptions,\n setSecurityHeaders,\n} from './http/security-headers.js'\n\nexport type WriteHtmlOptions = BuildDocumentOptions &\n WriteResponseOptions &\n SecurityHeadersOptions\n\nexport function writeHtml(\n res: ServerResponse,\n options: WriteHtmlOptions,\n): void {\n // @NOTE the csp string might be quite long. In that case it might be tempting\n // to set it through the http-equiv <meta> in the HTML. However, some\n // directives cannot be enforced by browsers when set through the meta tag\n // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the\n // HTTP header.\n const csp = mergeCsp(\n {\n // Keep \"upgrade-insecure-requests\" in sync with HSTS setting. HSTS is\n // typically set to false for localhost endpoints. Chrome and FF will\n // ignore \"upgrade-insecure-requests\" from localhost, but Safari will\n // enforce it, requiring to be explicitly disable it for localhost.\n 'upgrade-insecure-requests': options.hsts !== false,\n 'default-src': [\"'none'\"],\n 'base-uri': options.base?.origin as undefined | `https://${string}`,\n 'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),\n 'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),\n },\n options.csp,\n )\n\n const html = buildDocument(options).toString()\n\n // HTML pages should always be served with safety protection headers\n setSecurityHeaders(res, { ...options, csp })\n writeBuffer(res, html, {\n ...options,\n contentType: options?.contentType ?? 'text/html; charset=utf-8',\n })\n}\n\nfunction assetToCsp(asset?: Html | AssetRef): undefined | CspValue {\n if (asset == null) return undefined\n if (asset instanceof Html) {\n // Inline assets are \"allowed\" by their hash\n const hash = createHash('sha256')\n for (const fragment of asset) hash.update(fragment)\n return `'sha256-${hash.digest('base64')}'`\n } else {\n // External assets are referenced by their origin\n if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {\n return new URL(asset.url).origin as `https:${string}` | `http:${string}`\n }\n\n // Internal assets are served from the same origin\n return `'self'`\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { Keyset } from '@atproto/jwk';
2
- import { OAuthAuthorizationServerMetadata, OAuthIssuerIdentifier } from '@atproto/oauth-types';
1
+ import type { Keyset } from '@atproto/jwk';
2
+ import { type OAuthAuthorizationServerMetadata, type OAuthIssuerIdentifier } from '@atproto/oauth-types';
3
3
  export type CustomMetadata = {
4
4
  authorization_details_types_supported?: string[];
5
5
  protected_resources?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"build-metadata.d.ts","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EACL,gCAAgC,EAChC,qBAAqB,EAEtB,MAAM,sBAAsB,CAAA;AAI7B,MAAM,MAAM,cAAc,GAAG;IAC3B,qCAAqC,CAAC,EAAE,MAAM,EAAE,CAAA;IAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC/B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,cAAc,GAC9B,gCAAgC,CAqHlC"}
1
+ {"version":3,"file":"build-metadata.d.ts","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,qBAAqB,EAE3B,MAAM,sBAAsB,CAAA;AAI7B,MAAM,MAAM,cAAc,GAAG;IAC3B,qCAAqC,CAAC,EAAE,MAAM,EAAE,CAAA;IAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC/B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,cAAc,GAC9B,gCAAgC,CAqHlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"build-metadata.js","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,yCAAyC,GAC1C,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAOpD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA6B,EAC7B,MAAc,EACd,cAA+B;IAE/B,OAAO,yCAAyC,CAAC,KAAK,CAAC;QACrD,MAAM;QAEN,gBAAgB,EAAE;YAChB,SAAS;YAET,yEAAyE;YACzE,kCAAkC;YAClC,kBAAkB;YAClB,oBAAoB;YACpB,sBAAsB;YAEtB,gEAAgE;SACjE;QACD,uBAAuB,EAAE;YACvB,EAAE;YACF,QAAQ,EAAE,6CAA6C;YACvD,+DAA+D;SAChE;QACD,wBAAwB,EAAE;YACxB,QAAQ;YACR,MAAM;YACN,WAAW;YAEX,SAAS;YACT,UAAU;YACV,yBAAyB;YACzB,mBAAmB;YACnB,gBAAgB;YAChB,oBAAoB;YACpB,cAAc;SACf;QACD,wBAAwB,EAAE;YACxB,mFAAmF;YACnF,OAAO;YACP,UAAU;YACV,0FAA0F;YAC1F,WAAW;SACZ;QACD,qBAAqB,EAAE;YACrB,EAAE;YACF,oBAAoB;YACpB,eAAe;SAChB;QACD,gCAAgC,EAAE;YAChC,sGAAsG;YACtG,MAAM;YAEN,iCAAiC;YACjC,WAAW;SACZ;QACD,oBAAoB,EAAE;YACpB,EAAE;YACF,OAAO;SACR;QACD,wBAAwB,EAAE;YACxB,EAAE;YACF,MAAM;YACN,OAAO;YACP,OAAO;YACP,aAAa;SACd;QAED,iEAAiE;QACjE,uBAAuB,EAAE;YACvB,MAAM;YACN,OAAO;YACP,SAAS;YACT,gBAAgB;YAChB,QAAQ;SACT;QAED,gDAAgD;QAChD,8CAA8C,EAAE,IAAI;QAEpD,0DAA0D;QAC1D,2CAA2C,EAAE,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC;QACtE,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAC3D,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAE3D,2BAA2B,EAAE,IAAI;QACjC,+BAA+B,EAAE,IAAI;QACrC,gCAAgC,EAAE,IAAI;QAEtC,QAAQ,EAAE,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,IAAI;QAE7C,sBAAsB,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,IAAI;QAEhE,cAAc,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI;QACpD,qCAAqC,EAAE,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC;QACzE,gDAAgD,EAAE,CAAC,GAAG,YAAY,CAAC;QAEnE,mBAAmB,EAAE,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI;QAE1D,6CAA6C;QAC7C,qEAAqE;QACrE,+DAA+D;QAE/D,0DAA0D;QAC1D,qCAAqC,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI;QAEzE,qCAAqC,EAAE,IAAI;QAE3C,4DAA4D;QAC5D,iCAAiC,EAAE,CAAC,GAAG,YAAY,CAAC;QAEpD,6DAA6D;QAC7D,qCAAqC,EACnC,cAAc,EAAE,qCAAqC;QAEvD,wDAAwD;QACxD,mBAAmB,EAAE,cAAc,EAAE,mBAAmB;QAExD,uFAAuF;QACvF,qCAAqC,EAAE,IAAI;KAC5C,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Keyset } from '@atproto/jwk'\nimport {\n OAuthAuthorizationServerMetadata,\n OAuthIssuerIdentifier,\n oauthAuthorizationServerMetadataValidator,\n} from '@atproto/oauth-types'\nimport { Client } from '../client/client.js'\nimport { VERIFY_ALGOS } from '../lib/util/crypto.js'\n\nexport type CustomMetadata = {\n authorization_details_types_supported?: string[]\n protected_resources?: string[]\n}\n\n/**\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}\n * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}\n * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}\n */\nexport function buildMetadata(\n issuer: OAuthIssuerIdentifier,\n keyset: Keyset,\n customMetadata?: CustomMetadata,\n): OAuthAuthorizationServerMetadata {\n return oauthAuthorizationServerMetadataValidator.parse({\n issuer,\n\n scopes_supported: [\n 'atproto',\n\n // These serve as hint that this server supports the transitional scopes.\n // This is not a specced behavior.\n 'transition:email',\n 'transition:generic',\n 'transition:chat.bsky',\n\n // Other atproto scopes can't be enumerated as they are dynamic.\n ],\n subject_types_supported: [\n //\n 'public', // The same \"sub\" is returned for all clients\n // 'pairwise', // A different \"sub\" is returned for each client\n ],\n response_types_supported: [\n // OAuth\n 'code',\n // 'token',\n\n // OpenID\n // 'none',\n // 'code id_token token',\n // 'code id_token',\n // 'code token',\n // 'id_token token',\n // 'id_token',\n ],\n response_modes_supported: [\n // https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes\n 'query',\n 'fragment',\n // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode\n 'form_post',\n ],\n grant_types_supported: [\n //\n 'authorization_code',\n 'refresh_token',\n ],\n code_challenge_methods_supported: [\n // https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#pkce-code-challenge-method\n 'S256',\n\n // atproto does not allow \"plain\"\n // 'plain',\n ],\n ui_locales_supported: [\n //\n 'en-US',\n ],\n display_values_supported: [\n //\n 'page',\n 'popup',\n 'touch',\n // 'wap', LoL\n ],\n\n // https://openid.net/specs/openid-connect-prompt-create-1_0.html\n prompt_values_supported: [\n 'none',\n 'login',\n 'consent',\n 'select_account',\n 'create',\n ],\n\n // https://datatracker.ietf.org/doc/html/rfc9207\n authorization_response_iss_parameter_supported: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9101#section-4\n request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],\n request_object_encryption_alg_values_supported: [], // None\n request_object_encryption_enc_values_supported: [], // None\n\n request_parameter_supported: true,\n request_uri_parameter_supported: true,\n require_request_uri_registration: true,\n\n jwks_uri: new URL('/oauth/jwks', issuer).href,\n\n authorization_endpoint: new URL('/oauth/authorize', issuer).href,\n\n token_endpoint: new URL('/oauth/token', issuer).href,\n token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],\n token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n revocation_endpoint: new URL('/oauth/revoke', issuer).href,\n\n // @TODO Should we implement these endpoints?\n // introspection_endpoint: new URL('/oauth/introspect', issuer).href,\n // end_session_endpoint: new URL('/oauth/logout', issuer).href,\n\n // https://datatracker.ietf.org/doc/html/rfc9126#section-5\n pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,\n\n require_pushed_authorization_requests: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1\n dpop_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4\n authorization_details_types_supported:\n customMetadata?.authorization_details_types_supported,\n\n // https://www.rfc-editor.org/rfc/rfc9728.html#section-4\n protected_resources: customMetadata?.protected_resources,\n\n // https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html\n client_id_metadata_document_supported: true,\n })\n}\n"]}
1
+ {"version":3,"file":"build-metadata.js","sourceRoot":"","sources":["../../src/metadata/build-metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,yCAAyC,GAC1C,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAOpD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA6B,EAC7B,MAAc,EACd,cAA+B;IAE/B,OAAO,yCAAyC,CAAC,KAAK,CAAC;QACrD,MAAM;QAEN,gBAAgB,EAAE;YAChB,SAAS;YAET,yEAAyE;YACzE,kCAAkC;YAClC,kBAAkB;YAClB,oBAAoB;YACpB,sBAAsB;YAEtB,gEAAgE;SACjE;QACD,uBAAuB,EAAE;YACvB,EAAE;YACF,QAAQ,EAAE,6CAA6C;YACvD,+DAA+D;SAChE;QACD,wBAAwB,EAAE;YACxB,QAAQ;YACR,MAAM;YACN,WAAW;YAEX,SAAS;YACT,UAAU;YACV,yBAAyB;YACzB,mBAAmB;YACnB,gBAAgB;YAChB,oBAAoB;YACpB,cAAc;SACf;QACD,wBAAwB,EAAE;YACxB,mFAAmF;YACnF,OAAO;YACP,UAAU;YACV,0FAA0F;YAC1F,WAAW;SACZ;QACD,qBAAqB,EAAE;YACrB,EAAE;YACF,oBAAoB;YACpB,eAAe;SAChB;QACD,gCAAgC,EAAE;YAChC,sGAAsG;YACtG,MAAM;YAEN,iCAAiC;YACjC,WAAW;SACZ;QACD,oBAAoB,EAAE;YACpB,EAAE;YACF,OAAO;SACR;QACD,wBAAwB,EAAE;YACxB,EAAE;YACF,MAAM;YACN,OAAO;YACP,OAAO;YACP,aAAa;SACd;QAED,iEAAiE;QACjE,uBAAuB,EAAE;YACvB,MAAM;YACN,OAAO;YACP,SAAS;YACT,gBAAgB;YAChB,QAAQ;SACT;QAED,gDAAgD;QAChD,8CAA8C,EAAE,IAAI;QAEpD,0DAA0D;QAC1D,2CAA2C,EAAE,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC;QACtE,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAC3D,8CAA8C,EAAE,EAAE,EAAE,OAAO;QAE3D,2BAA2B,EAAE,IAAI;QACjC,+BAA+B,EAAE,IAAI;QACrC,gCAAgC,EAAE,IAAI;QAEtC,QAAQ,EAAE,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,IAAI;QAE7C,sBAAsB,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,IAAI;QAEhE,cAAc,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI;QACpD,qCAAqC,EAAE,CAAC,GAAG,MAAM,CAAC,sBAAsB,CAAC;QACzE,gDAAgD,EAAE,CAAC,GAAG,YAAY,CAAC;QAEnE,mBAAmB,EAAE,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI;QAE1D,6CAA6C;QAC7C,qEAAqE;QACrE,+DAA+D;QAE/D,0DAA0D;QAC1D,qCAAqC,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI;QAEzE,qCAAqC,EAAE,IAAI;QAE3C,4DAA4D;QAC5D,iCAAiC,EAAE,CAAC,GAAG,YAAY,CAAC;QAEpD,6DAA6D;QAC7D,qCAAqC,EACnC,cAAc,EAAE,qCAAqC;QAEvD,wDAAwD;QACxD,mBAAmB,EAAE,cAAc,EAAE,mBAAmB;QAExD,uFAAuF;QACvF,qCAAqC,EAAE,IAAI;KAC5C,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { Keyset } from '@atproto/jwk'\nimport {\n type OAuthAuthorizationServerMetadata,\n type OAuthIssuerIdentifier,\n oauthAuthorizationServerMetadataValidator,\n} from '@atproto/oauth-types'\nimport { Client } from '../client/client.js'\nimport { VERIFY_ALGOS } from '../lib/util/crypto.js'\n\nexport type CustomMetadata = {\n authorization_details_types_supported?: string[]\n protected_resources?: string[]\n}\n\n/**\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}\n * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}\n * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}\n */\nexport function buildMetadata(\n issuer: OAuthIssuerIdentifier,\n keyset: Keyset,\n customMetadata?: CustomMetadata,\n): OAuthAuthorizationServerMetadata {\n return oauthAuthorizationServerMetadataValidator.parse({\n issuer,\n\n scopes_supported: [\n 'atproto',\n\n // These serve as hint that this server supports the transitional scopes.\n // This is not a specced behavior.\n 'transition:email',\n 'transition:generic',\n 'transition:chat.bsky',\n\n // Other atproto scopes can't be enumerated as they are dynamic.\n ],\n subject_types_supported: [\n //\n 'public', // The same \"sub\" is returned for all clients\n // 'pairwise', // A different \"sub\" is returned for each client\n ],\n response_types_supported: [\n // OAuth\n 'code',\n // 'token',\n\n // OpenID\n // 'none',\n // 'code id_token token',\n // 'code id_token',\n // 'code token',\n // 'id_token token',\n // 'id_token',\n ],\n response_modes_supported: [\n // https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes\n 'query',\n 'fragment',\n // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode\n 'form_post',\n ],\n grant_types_supported: [\n //\n 'authorization_code',\n 'refresh_token',\n ],\n code_challenge_methods_supported: [\n // https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#pkce-code-challenge-method\n 'S256',\n\n // atproto does not allow \"plain\"\n // 'plain',\n ],\n ui_locales_supported: [\n //\n 'en-US',\n ],\n display_values_supported: [\n //\n 'page',\n 'popup',\n 'touch',\n // 'wap', LoL\n ],\n\n // https://openid.net/specs/openid-connect-prompt-create-1_0.html\n prompt_values_supported: [\n 'none',\n 'login',\n 'consent',\n 'select_account',\n 'create',\n ],\n\n // https://datatracker.ietf.org/doc/html/rfc9207\n authorization_response_iss_parameter_supported: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9101#section-4\n request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],\n request_object_encryption_alg_values_supported: [], // None\n request_object_encryption_enc_values_supported: [], // None\n\n request_parameter_supported: true,\n request_uri_parameter_supported: true,\n require_request_uri_registration: true,\n\n jwks_uri: new URL('/oauth/jwks', issuer).href,\n\n authorization_endpoint: new URL('/oauth/authorize', issuer).href,\n\n token_endpoint: new URL('/oauth/token', issuer).href,\n token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],\n token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n revocation_endpoint: new URL('/oauth/revoke', issuer).href,\n\n // @TODO Should we implement these endpoints?\n // introspection_endpoint: new URL('/oauth/introspect', issuer).href,\n // end_session_endpoint: new URL('/oauth/logout', issuer).href,\n\n // https://datatracker.ietf.org/doc/html/rfc9126#section-5\n pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,\n\n require_pushed_authorization_requests: true,\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1\n dpop_signing_alg_values_supported: [...VERIFY_ALGOS],\n\n // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4\n authorization_details_types_supported:\n customMetadata?.authorization_details_types_supported,\n\n // https://www.rfc-editor.org/rfc/rfc9728.html#section-4\n protected_resources: customMetadata?.protected_resources,\n\n // https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html\n client_id_metadata_document_supported: true,\n })\n}\n"]}
@@ -47,4 +47,4 @@ export declare const CODE_CHALLENGE_REPLAY_TIMEFRAME: number;
47
47
  /** 5 minutes */
48
48
  export declare const LEXICON_REFRESH_FREQUENCY: number;
49
49
  export declare const NODE_ENV: string;
50
- //# sourceMappingURL=constants.d.ts.map
50
+ //# sourceMappingURL=oauth-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-constants.d.ts","sourceRoot":"","sources":["../src/oauth-constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,SAAS,CAAA;AACtC,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,eAAO,MAAM,iBAAiB,SAAS,CAAA;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,eAAO,MAAM,oBAAoB,SAAS,CAAA;AAC1C,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAE5C,eAAO,MAAM,eAAe,SAAS,CAAA;AACrC,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC,eAAO,MAAM,iBAAiB,SAAS,CAAA;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,eAAO,MAAM,WAAW,SAAS,CAAA;AACjC,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAUnC,aAAa;AACb,eAAO,MAAM,sBAAsB,QAAU,CAAA;AAE7C,iBAAiB;AACjB,eAAO,MAAM,yBAAyB,QAAc,CAAA;AAEpD,iBAAiB;AACjB,eAAO,MAAM,aAAa,QAAc,CAAA;AAExC,gBAAgB;AAChB,eAAO,MAAM,gCAAgC,QAAa,CAAA;AAE1D,aAAa;AACb,eAAO,MAAM,8BAA8B,QAAW,CAAA;AAEtD,kDAAkD;AAClD,eAAO,MAAM,8BAA8B,QAAiC,CAAA;AAE5E,cAAc;AACd,eAAO,MAAM,oCAAoC,QAAW,CAAA;AAE5D,eAAe;AACf,eAAO,MAAM,oCAAoC,QAAY,CAAA;AAE7D,gBAAgB;AAChB,eAAO,MAAM,cAAc,QAAa,CAAA;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,QAAc,CAAA;AAEtC,eAAe;AACf,eAAO,MAAM,wBAAwB,QAAa,CAAA;AAElD,gBAAgB;AAChB,eAAO,MAAM,kBAAkB,QAAa,CAAA;AAE5C,gBAAgB;AAChB,eAAO,MAAM,wBAAwB,QAAa,CAAA;AAElD,YAAY;AACZ,eAAO,MAAM,+BAA+B,QAAU,CAAA;AAEtD,gBAAgB;AAChB,eAAO,MAAM,yBAAyB,QAAa,CAAA;AAEnD,eAAO,MAAM,QAAQ,QAAuC,CAAA"}
@@ -55,4 +55,4 @@ export const CODE_CHALLENGE_REPLAY_TIMEFRAME = 1 * DAY;
55
55
  /** 5 minutes */
56
56
  export const LEXICON_REFRESH_FREQUENCY = 5 * MINUTE;
57
57
  export const NODE_ENV = process.env.NODE_ENV || 'production';
58
- //# sourceMappingURL=constants.js.map
58
+ //# sourceMappingURL=oauth-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-constants.js","sourceRoot":"","sources":["../src/oauth-constants.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAA;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAA,CAAC,WAAW;AAEpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAA;AACvC,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAA,CAAC,8CAA8C;AAExF,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAC1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAA,CAAC,WAAW;AAExD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAA;AACrC,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA,CAAC,sDAAsD;AAE9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAA;AACvC,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAA,CAAC,WAAW;AAErD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAA;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC,MAAM,MAAM,GAAG,GAAG,CAAA;AAClB,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAA;AAC1B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAA;AACxB,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAA;AACrB,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,CAAA;AACpB,MAAM,IAAI,GAAG,MAAM,GAAG,GAAG,CAAA;AACzB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAA;AAEvB,aAAa;AACb,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,GAAG,CAAA;AAE7C,iBAAiB;AACjB,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,MAAM,CAAA;AAEpD,iBAAiB;AACjB,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAA;AAExC,gBAAgB;AAChB,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,GAAG,MAAM,CAAA;AAE1D,aAAa;AACb,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,GAAG,IAAI,CAAA;AAEtD,kDAAkD;AAClD,MAAM,CAAC,MAAM,8BAA8B,GAAG,8BAA8B,CAAA;AAE5E,cAAc;AACd,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,GAAG,IAAI,CAAA;AAE5D,eAAe;AACf,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE7D,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAG,MAAM,CAAA;AAExC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,GAAG,MAAM,CAAA;AAEtC,eAAe;AACf,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,MAAM,CAAA;AAElD,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,MAAM,CAAA;AAE5C,gBAAgB;AAChB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,MAAM,CAAA;AAElD,YAAY;AACZ,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,GAAG,GAAG,CAAA;AAEtD,gBAAgB;AAChB,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,MAAM,CAAA;AAEnD,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,YAAY,CAAA","sourcesContent":["// The purpose of the prefix is to provide type safety\n\nexport const DEVICE_ID_PREFIX = 'dev-'\nexport const DEVICE_ID_BYTES_LENGTH = 16 // 128 bits\n\nexport const SESSION_ID_PREFIX = 'ses-'\nexport const SESSION_ID_BYTES_LENGTH = 16 // 128 bits - only valid if device id is valid\n\nexport const REFRESH_TOKEN_PREFIX = 'ref-'\nexport const REFRESH_TOKEN_BYTES_LENGTH = 32 // 256 bits\n\nexport const TOKEN_ID_PREFIX = 'tok-'\nexport const TOKEN_ID_BYTES_LENGTH = 16 // 128 bits - used as `jti` in JWTs (cannot be forged)\n\nexport const REQUEST_ID_PREFIX = 'req-'\nexport const REQUEST_ID_BYTES_LENGTH = 16 // 128 bits\n\nexport const CODE_PREFIX = 'cod-'\nexport const CODE_BYTES_LENGTH = 32\n\nconst SECOND = 1e3\nconst MINUTE = 60 * SECOND\nconst HOUR = 60 * MINUTE\nconst DAY = 24 * HOUR\nconst WEEK = 7 * DAY\nconst YEAR = 365.25 * DAY\nconst MONTH = YEAR / 12\n\n/** 7 days */\nexport const AUTHENTICATION_MAX_AGE = 7 * DAY\n\n/** 15 minutes */\nexport const EPHEMERAL_SESSION_MAX_AGE = 15 * MINUTE\n\n/** 60 minutes */\nexport const TOKEN_MAX_AGE = 60 * MINUTE\n\n/** 5 minutes */\nexport const AUTHORIZATION_INACTIVITY_TIMEOUT = 5 * MINUTE\n\n/** 2 week */\nexport const PUBLIC_CLIENT_SESSION_LIFETIME = 2 * WEEK\n\n/** @see {@link PUBLIC_CLIENT_SESSION_LIFETIME} */\nexport const PUBLIC_CLIENT_REFRESH_LIFETIME = PUBLIC_CLIENT_SESSION_LIFETIME\n\n/** 2 years */\nexport const CONFIDENTIAL_CLIENT_SESSION_LIFETIME = 2 * YEAR\n\n/** 3 months */\nexport const CONFIDENTIAL_CLIENT_REFRESH_LIFETIME = 3 * MONTH\n\n/** 5 minutes */\nexport const PAR_EXPIRES_IN = 5 * MINUTE\n\n/**\n * 59 seconds (should be less than a minute)\n *\n * > \"A general guidance for the validity time would be less than a minute.\"\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc9101#section-10.2 | JWT-Secured Authorization Request (JAR) - Section 10.2 (d)}\n */\nexport const JAR_MAX_AGE = 59 * SECOND\n\n/** 1 minute */\nexport const CLIENT_ASSERTION_MAX_AGE = 1 * MINUTE\n\n/** 3 minutes */\nexport const DPOP_NONCE_MAX_AGE = 3 * MINUTE\n\n/** 5 seconds */\nexport const SESSION_FIXATION_MAX_AGE = 5 * SECOND\n\n/** 1 day */\nexport const CODE_CHALLENGE_REPLAY_TIMEFRAME = 1 * DAY\n\n/** 5 minutes */\nexport const LEXICON_REFRESH_FREQUENCY = 5 * MINUTE\n\nexport const NODE_ENV = process.env.NODE_ENV || 'production'\n"]}
@@ -1,9 +1,9 @@
1
- export { OAuthError } from './errors/oauth-error.js';
1
+ export * from './errors/oauth-error.js';
2
+ export * from './errors/handle-unavailable-error.js';
2
3
  export * from './errors/access-denied-error.js';
3
4
  export * from './errors/account-selection-required-error.js';
4
5
  export * from './errors/authorization-error.js';
5
6
  export * from './errors/consent-required-error.js';
6
- export * from './errors/handle-unavailable-error.js';
7
7
  export * from './errors/invalid-authorization-details-error.js';
8
8
  export * from './errors/invalid-client-error.js';
9
9
  export * from './errors/invalid-client-id-error.js';
@@ -12,7 +12,6 @@ export * from './errors/invalid-credentials-error.js';
12
12
  export * from './errors/invalid-dpop-key-binding-error.js';
13
13
  export * from './errors/invalid-dpop-proof-error.js';
14
14
  export * from './errors/invalid-grant-error.js';
15
- export * from './errors/invalid-invite-code-error.js';
16
15
  export * from './errors/invalid-redirect-uri-error.js';
17
16
  export * from './errors/invalid-request-error.js';
18
17
  export * from './errors/invalid-scope-error.js';
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-errors.d.ts","sourceRoot":"","sources":["../src/oauth-errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8CAA8C,CAAA;AAC5D,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA;AACpD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,2CAA2C,CAAA;AACzD,cAAc,uCAAuC,CAAA;AACrD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,uCAAuC,CAAA;AACrD,cAAc,wCAAwC,CAAA;AACtD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,yDAAyD,CAAA;AACvE,cAAc,uCAAuC,CAAA;AACrD,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA"}
1
+ {"version":3,"file":"oauth-errors.d.ts","sourceRoot":"","sources":["../src/oauth-errors.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AAGvC,cAAc,sCAAsC,CAAA;AAGpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8CAA8C,CAAA;AAC5D,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,2CAA2C,CAAA;AACzD,cAAc,uCAAuC,CAAA;AACrD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,wCAAwC,CAAA;AACtD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,yDAAyD,CAAA;AACvE,cAAc,uCAAuC,CAAA;AACrD,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA"}
@@ -1,10 +1,11 @@
1
- // Root Error class
2
- export { OAuthError } from './errors/oauth-error.js';
1
+ export * from './errors/oauth-error.js';
2
+ // API error
3
+ export * from './errors/handle-unavailable-error.js';
4
+ // OAuthError sub-classes
3
5
  export * from './errors/access-denied-error.js';
4
6
  export * from './errors/account-selection-required-error.js';
5
7
  export * from './errors/authorization-error.js';
6
8
  export * from './errors/consent-required-error.js';
7
- export * from './errors/handle-unavailable-error.js';
8
9
  export * from './errors/invalid-authorization-details-error.js';
9
10
  export * from './errors/invalid-client-error.js';
10
11
  export * from './errors/invalid-client-id-error.js';
@@ -13,7 +14,6 @@ export * from './errors/invalid-credentials-error.js';
13
14
  export * from './errors/invalid-dpop-key-binding-error.js';
14
15
  export * from './errors/invalid-dpop-proof-error.js';
15
16
  export * from './errors/invalid-grant-error.js';
16
- export * from './errors/invalid-invite-code-error.js';
17
17
  export * from './errors/invalid-redirect-uri-error.js';
18
18
  export * from './errors/invalid-request-error.js';
19
19
  export * from './errors/invalid-scope-error.js';
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-errors.js","sourceRoot":"","sources":["../src/oauth-errors.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8CAA8C,CAAA;AAC5D,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA;AACpD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,2CAA2C,CAAA;AACzD,cAAc,uCAAuC,CAAA;AACrD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,uCAAuC,CAAA;AACrD,cAAc,wCAAwC,CAAA;AACtD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,yDAAyD,CAAA;AACvE,cAAc,uCAAuC,CAAA;AACrD,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA","sourcesContent":["// Root Error class\nexport { OAuthError } from './errors/oauth-error.js'\n\nexport * from './errors/access-denied-error.js'\nexport * from './errors/account-selection-required-error.js'\nexport * from './errors/authorization-error.js'\nexport * from './errors/consent-required-error.js'\nexport * from './errors/handle-unavailable-error.js'\nexport * from './errors/invalid-authorization-details-error.js'\nexport * from './errors/invalid-client-error.js'\nexport * from './errors/invalid-client-id-error.js'\nexport * from './errors/invalid-client-metadata-error.js'\nexport * from './errors/invalid-credentials-error.js'\nexport * from './errors/invalid-dpop-key-binding-error.js'\nexport * from './errors/invalid-dpop-proof-error.js'\nexport * from './errors/invalid-grant-error.js'\nexport * from './errors/invalid-invite-code-error.js'\nexport * from './errors/invalid-redirect-uri-error.js'\nexport * from './errors/invalid-request-error.js'\nexport * from './errors/invalid-scope-error.js'\nexport * from './errors/invalid-token-error.js'\nexport * from './errors/login-required-error.js'\nexport * from './errors/second-authentication-factor-required-error.js'\nexport * from './errors/unauthorized-client-error.js'\nexport * from './errors/use-dpop-nonce-error.js'\nexport * from './errors/www-authenticate-error.js'\n"]}
1
+ {"version":3,"file":"oauth-errors.js","sourceRoot":"","sources":["../src/oauth-errors.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AAEvC,YAAY;AACZ,cAAc,sCAAsC,CAAA;AAEpD,yBAAyB;AACzB,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8CAA8C,CAAA;AAC5D,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oCAAoC,CAAA;AAClD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,2CAA2C,CAAA;AACzD,cAAc,uCAAuC,CAAA;AACrD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,sCAAsC,CAAA;AACpD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,wCAAwC,CAAA;AACtD,cAAc,mCAAmC,CAAA;AACjD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,yDAAyD,CAAA;AACvE,cAAc,uCAAuC,CAAA;AACrD,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA","sourcesContent":["export * from './errors/oauth-error.js'\n\n// API error\nexport * from './errors/handle-unavailable-error.js'\n\n// OAuthError sub-classes\nexport * from './errors/access-denied-error.js'\nexport * from './errors/account-selection-required-error.js'\nexport * from './errors/authorization-error.js'\nexport * from './errors/consent-required-error.js'\nexport * from './errors/invalid-authorization-details-error.js'\nexport * from './errors/invalid-client-error.js'\nexport * from './errors/invalid-client-id-error.js'\nexport * from './errors/invalid-client-metadata-error.js'\nexport * from './errors/invalid-credentials-error.js'\nexport * from './errors/invalid-dpop-key-binding-error.js'\nexport * from './errors/invalid-dpop-proof-error.js'\nexport * from './errors/invalid-grant-error.js'\nexport * from './errors/invalid-redirect-uri-error.js'\nexport * from './errors/invalid-request-error.js'\nexport * from './errors/invalid-scope-error.js'\nexport * from './errors/invalid-token-error.js'\nexport * from './errors/login-required-error.js'\nexport * from './errors/second-authentication-factor-required-error.js'\nexport * from './errors/unauthorized-client-error.js'\nexport * from './errors/use-dpop-nonce-error.js'\nexport * from './errors/www-authenticate-error.js'\n"]}