hooklatch 0.0.0-stage → 1.0.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 (301) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +438 -2
  3. package/dist/adapters/cloudflare.d.ts +11 -0
  4. package/dist/adapters/cloudflare.d.ts.map +1 -0
  5. package/dist/adapters/cloudflare.js +27 -0
  6. package/dist/adapters/cloudflare.js.map +1 -0
  7. package/dist/adapters/express.d.ts +9 -0
  8. package/dist/adapters/express.d.ts.map +1 -0
  9. package/dist/adapters/express.js +63 -0
  10. package/dist/adapters/express.js.map +1 -0
  11. package/dist/adapters/hono.d.ts +12 -0
  12. package/dist/adapters/hono.d.ts.map +1 -0
  13. package/dist/adapters/hono.js +28 -0
  14. package/dist/adapters/hono.js.map +1 -0
  15. package/dist/adapters/nextjs.d.ts +6 -0
  16. package/dist/adapters/nextjs.d.ts.map +1 -0
  17. package/dist/adapters/nextjs.js +56 -0
  18. package/dist/adapters/nextjs.js.map +1 -0
  19. package/dist/adapters/shared.d.ts +8 -0
  20. package/dist/adapters/shared.d.ts.map +1 -0
  21. package/dist/adapters/shared.js +53 -0
  22. package/dist/adapters/shared.js.map +1 -0
  23. package/dist/cjs/adapters/cloudflare.cjs +29 -0
  24. package/dist/cjs/adapters/cloudflare.d.cts +10 -0
  25. package/dist/cjs/adapters/express.cjs +65 -0
  26. package/dist/cjs/adapters/express.d.cts +8 -0
  27. package/dist/cjs/adapters/hono.cjs +30 -0
  28. package/dist/cjs/adapters/hono.d.cts +11 -0
  29. package/dist/cjs/adapters/nextjs.cjs +58 -0
  30. package/dist/cjs/adapters/nextjs.d.cts +5 -0
  31. package/dist/cjs/adapters/shared.cjs +58 -0
  32. package/dist/cjs/adapters/shared.d.cts +7 -0
  33. package/dist/cjs/core.cjs +30 -0
  34. package/dist/cjs/core.d.cts +5 -0
  35. package/dist/cjs/diagnostics/catalog.cjs +341 -0
  36. package/dist/cjs/diagnostics/catalog.d.cts +19 -0
  37. package/dist/cjs/diagnostics/index.cjs +90 -0
  38. package/dist/cjs/diagnostics/index.d.cts +5 -0
  39. package/dist/cjs/diagnostics/types.cjs +2 -0
  40. package/dist/cjs/diagnostics/types.d.cts +20 -0
  41. package/dist/cjs/errors.cjs +13 -0
  42. package/dist/cjs/errors.d.cts +6 -0
  43. package/dist/cjs/index.cjs +9 -0
  44. package/dist/cjs/index.d.cts +3 -0
  45. package/dist/cjs/internal/body.cjs +50 -0
  46. package/dist/cjs/internal/body.d.cts +2 -0
  47. package/dist/cjs/internal/bytes.cjs +43 -0
  48. package/dist/cjs/internal/bytes.d.cts +4 -0
  49. package/dist/cjs/internal/crypto.cjs +52 -0
  50. package/dist/cjs/internal/crypto.d.cts +3 -0
  51. package/dist/cjs/internal/headers.cjs +72 -0
  52. package/dist/cjs/internal/headers.d.cts +2 -0
  53. package/dist/cjs/internal/options.cjs +130 -0
  54. package/dist/cjs/internal/options.d.cts +7 -0
  55. package/dist/cjs/internal/prepare.cjs +11 -0
  56. package/dist/cjs/internal/prepare.d.cts +4 -0
  57. package/dist/cjs/internal/provider-options.cjs +72 -0
  58. package/dist/cjs/internal/provider-options.d.cts +6 -0
  59. package/dist/cjs/internal/provider.cjs +2 -0
  60. package/dist/cjs/internal/provider.d.cts +39 -0
  61. package/dist/cjs/internal/verification.cjs +71 -0
  62. package/dist/cjs/internal/verification.d.cts +12 -0
  63. package/dist/cjs/providers/clerk.cjs +15 -0
  64. package/dist/cjs/providers/clerk.d.cts +9 -0
  65. package/dist/cjs/providers/dodo-payments.cjs +26 -0
  66. package/dist/cjs/providers/dodo-payments.d.cts +20 -0
  67. package/dist/cjs/providers/doppler.cjs +71 -0
  68. package/dist/cjs/providers/doppler.d.cts +37 -0
  69. package/dist/cjs/providers/fal.cjs +80 -0
  70. package/dist/cjs/providers/fal.d.cts +13 -0
  71. package/dist/cjs/providers/github.cjs +52 -0
  72. package/dist/cjs/providers/github.d.cts +7 -0
  73. package/dist/cjs/providers/gitlab.cjs +26 -0
  74. package/dist/cjs/providers/gitlab.d.cts +20 -0
  75. package/dist/cjs/providers/grafana.cjs +180 -0
  76. package/dist/cjs/providers/grafana.d.cts +35 -0
  77. package/dist/cjs/providers/index.cjs +110 -0
  78. package/dist/cjs/providers/index.d.cts +26 -0
  79. package/dist/cjs/providers/lemon-squeezy.cjs +36 -0
  80. package/dist/cjs/providers/lemon-squeezy.d.cts +15 -0
  81. package/dist/cjs/providers/linear.cjs +58 -0
  82. package/dist/cjs/providers/linear.d.cts +36 -0
  83. package/dist/cjs/providers/paddle.cjs +105 -0
  84. package/dist/cjs/providers/paddle.d.cts +14 -0
  85. package/dist/cjs/providers/polar.cjs +80 -0
  86. package/dist/cjs/providers/polar.d.cts +25 -0
  87. package/dist/cjs/providers/razorpay.cjs +43 -0
  88. package/dist/cjs/providers/razorpay.d.cts +19 -0
  89. package/dist/cjs/providers/replicate.cjs +25 -0
  90. package/dist/cjs/providers/replicate.d.cts +19 -0
  91. package/dist/cjs/providers/sanity.cjs +161 -0
  92. package/dist/cjs/providers/sanity.d.cts +38 -0
  93. package/dist/cjs/providers/sentry.cjs +47 -0
  94. package/dist/cjs/providers/sentry.d.cts +25 -0
  95. package/dist/cjs/providers/shared.cjs +49 -0
  96. package/dist/cjs/providers/shared.d.cts +14 -0
  97. package/dist/cjs/providers/shopify.cjs +40 -0
  98. package/dist/cjs/providers/shopify.d.cts +8 -0
  99. package/dist/cjs/providers/standard-webhooks-protocol.cjs +97 -0
  100. package/dist/cjs/providers/standard-webhooks-protocol.d.cts +14 -0
  101. package/dist/cjs/providers/standard-webhooks.cjs +15 -0
  102. package/dist/cjs/providers/standard-webhooks.d.cts +9 -0
  103. package/dist/cjs/providers/stripe.cjs +81 -0
  104. package/dist/cjs/providers/stripe.d.cts +7 -0
  105. package/dist/cjs/providers/svix.cjs +63 -0
  106. package/dist/cjs/providers/svix.d.cts +9 -0
  107. package/dist/cjs/providers/vercel.cjs +39 -0
  108. package/dist/cjs/providers/vercel.d.cts +15 -0
  109. package/dist/cjs/providers/workos.cjs +120 -0
  110. package/dist/cjs/providers/workos.d.cts +32 -0
  111. package/dist/cjs/types.cjs +2 -0
  112. package/dist/cjs/types.d.cts +68 -0
  113. package/dist/cli/args.d.ts +86 -0
  114. package/dist/cli/args.d.ts.map +1 -0
  115. package/dist/cli/args.js +358 -0
  116. package/dist/cli/args.js.map +1 -0
  117. package/dist/cli/filesystem.d.ts +15 -0
  118. package/dist/cli/filesystem.d.ts.map +1 -0
  119. package/dist/cli/filesystem.js +170 -0
  120. package/dist/cli/filesystem.js.map +1 -0
  121. package/dist/cli/index.d.ts +3 -0
  122. package/dist/cli/index.d.ts.map +1 -0
  123. package/dist/cli/index.js +64 -0
  124. package/dist/cli/index.js.map +1 -0
  125. package/dist/cli/templates.d.ts +13 -0
  126. package/dist/cli/templates.d.ts.map +1 -0
  127. package/dist/cli/templates.js +297 -0
  128. package/dist/cli/templates.js.map +1 -0
  129. package/dist/core.d.ts +6 -0
  130. package/dist/core.d.ts.map +1 -0
  131. package/dist/core.js +26 -0
  132. package/dist/core.js.map +1 -0
  133. package/dist/diagnostics/catalog.d.ts +20 -0
  134. package/dist/diagnostics/catalog.d.ts.map +1 -0
  135. package/dist/diagnostics/catalog.js +335 -0
  136. package/dist/diagnostics/catalog.js.map +1 -0
  137. package/dist/diagnostics/index.d.ts +6 -0
  138. package/dist/diagnostics/index.d.ts.map +1 -0
  139. package/dist/diagnostics/index.js +88 -0
  140. package/dist/diagnostics/index.js.map +1 -0
  141. package/dist/diagnostics/types.d.ts +21 -0
  142. package/dist/diagnostics/types.d.ts.map +1 -0
  143. package/dist/diagnostics/types.js +2 -0
  144. package/dist/diagnostics/types.js.map +1 -0
  145. package/dist/errors.d.ts +7 -0
  146. package/dist/errors.d.ts.map +1 -0
  147. package/dist/errors.js +10 -0
  148. package/dist/errors.js.map +1 -0
  149. package/dist/index.d.ts +4 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +3 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/internal/body.d.ts +3 -0
  154. package/dist/internal/body.d.ts.map +1 -0
  155. package/dist/internal/body.js +48 -0
  156. package/dist/internal/body.js.map +1 -0
  157. package/dist/internal/bytes.d.ts +5 -0
  158. package/dist/internal/bytes.d.ts.map +1 -0
  159. package/dist/internal/bytes.js +38 -0
  160. package/dist/internal/bytes.js.map +1 -0
  161. package/dist/internal/crypto.d.ts +4 -0
  162. package/dist/internal/crypto.d.ts.map +1 -0
  163. package/dist/internal/crypto.js +49 -0
  164. package/dist/internal/crypto.js.map +1 -0
  165. package/dist/internal/headers.d.ts +3 -0
  166. package/dist/internal/headers.d.ts.map +1 -0
  167. package/dist/internal/headers.js +70 -0
  168. package/dist/internal/headers.js.map +1 -0
  169. package/dist/internal/options.d.ts +8 -0
  170. package/dist/internal/options.d.ts.map +1 -0
  171. package/dist/internal/options.js +128 -0
  172. package/dist/internal/options.js.map +1 -0
  173. package/dist/internal/prepare.d.ts +5 -0
  174. package/dist/internal/prepare.d.ts.map +1 -0
  175. package/dist/internal/prepare.js +9 -0
  176. package/dist/internal/prepare.js.map +1 -0
  177. package/dist/internal/provider-options.d.ts +7 -0
  178. package/dist/internal/provider-options.d.ts.map +1 -0
  179. package/dist/internal/provider-options.js +69 -0
  180. package/dist/internal/provider-options.js.map +1 -0
  181. package/dist/internal/provider.d.ts +40 -0
  182. package/dist/internal/provider.d.ts.map +1 -0
  183. package/dist/internal/provider.js +2 -0
  184. package/dist/internal/provider.js.map +1 -0
  185. package/dist/internal/verification.d.ts +13 -0
  186. package/dist/internal/verification.d.ts.map +1 -0
  187. package/dist/internal/verification.js +66 -0
  188. package/dist/internal/verification.js.map +1 -0
  189. package/dist/node/adapters/cloudflare.d.ts +1 -0
  190. package/dist/node/adapters/cloudflare.js +3 -0
  191. package/dist/node/adapters/express.d.ts +1 -0
  192. package/dist/node/adapters/express.js +3 -0
  193. package/dist/node/adapters/hono.d.ts +1 -0
  194. package/dist/node/adapters/hono.js +3 -0
  195. package/dist/node/adapters/nextjs.d.ts +1 -0
  196. package/dist/node/adapters/nextjs.js +3 -0
  197. package/dist/node/diagnostics/index.d.ts +1 -0
  198. package/dist/node/diagnostics/index.js +3 -0
  199. package/dist/node/index.d.ts +1 -0
  200. package/dist/node/index.js +6 -0
  201. package/dist/providers/clerk.d.ts +10 -0
  202. package/dist/providers/clerk.d.ts.map +1 -0
  203. package/dist/providers/clerk.js +13 -0
  204. package/dist/providers/clerk.js.map +1 -0
  205. package/dist/providers/dodo-payments.d.ts +21 -0
  206. package/dist/providers/dodo-payments.d.ts.map +1 -0
  207. package/dist/providers/dodo-payments.js +24 -0
  208. package/dist/providers/dodo-payments.js.map +1 -0
  209. package/dist/providers/doppler.d.ts +38 -0
  210. package/dist/providers/doppler.d.ts.map +1 -0
  211. package/dist/providers/doppler.js +69 -0
  212. package/dist/providers/doppler.js.map +1 -0
  213. package/dist/providers/fal.d.ts +14 -0
  214. package/dist/providers/fal.d.ts.map +1 -0
  215. package/dist/providers/fal.js +78 -0
  216. package/dist/providers/fal.js.map +1 -0
  217. package/dist/providers/github.d.ts +8 -0
  218. package/dist/providers/github.d.ts.map +1 -0
  219. package/dist/providers/github.js +50 -0
  220. package/dist/providers/github.js.map +1 -0
  221. package/dist/providers/gitlab.d.ts +21 -0
  222. package/dist/providers/gitlab.d.ts.map +1 -0
  223. package/dist/providers/gitlab.js +24 -0
  224. package/dist/providers/gitlab.js.map +1 -0
  225. package/dist/providers/grafana.d.ts +36 -0
  226. package/dist/providers/grafana.d.ts.map +1 -0
  227. package/dist/providers/grafana.js +178 -0
  228. package/dist/providers/grafana.js.map +1 -0
  229. package/dist/providers/index.d.ts +27 -0
  230. package/dist/providers/index.d.ts.map +1 -0
  231. package/dist/providers/index.js +89 -0
  232. package/dist/providers/index.js.map +1 -0
  233. package/dist/providers/lemon-squeezy.d.ts +16 -0
  234. package/dist/providers/lemon-squeezy.d.ts.map +1 -0
  235. package/dist/providers/lemon-squeezy.js +34 -0
  236. package/dist/providers/lemon-squeezy.js.map +1 -0
  237. package/dist/providers/linear.d.ts +37 -0
  238. package/dist/providers/linear.d.ts.map +1 -0
  239. package/dist/providers/linear.js +56 -0
  240. package/dist/providers/linear.js.map +1 -0
  241. package/dist/providers/paddle.d.ts +15 -0
  242. package/dist/providers/paddle.d.ts.map +1 -0
  243. package/dist/providers/paddle.js +103 -0
  244. package/dist/providers/paddle.js.map +1 -0
  245. package/dist/providers/polar.d.ts +26 -0
  246. package/dist/providers/polar.d.ts.map +1 -0
  247. package/dist/providers/polar.js +78 -0
  248. package/dist/providers/polar.js.map +1 -0
  249. package/dist/providers/razorpay.d.ts +20 -0
  250. package/dist/providers/razorpay.d.ts.map +1 -0
  251. package/dist/providers/razorpay.js +41 -0
  252. package/dist/providers/razorpay.js.map +1 -0
  253. package/dist/providers/replicate.d.ts +20 -0
  254. package/dist/providers/replicate.d.ts.map +1 -0
  255. package/dist/providers/replicate.js +23 -0
  256. package/dist/providers/replicate.js.map +1 -0
  257. package/dist/providers/sanity.d.ts +39 -0
  258. package/dist/providers/sanity.d.ts.map +1 -0
  259. package/dist/providers/sanity.js +159 -0
  260. package/dist/providers/sanity.js.map +1 -0
  261. package/dist/providers/sentry.d.ts +26 -0
  262. package/dist/providers/sentry.d.ts.map +1 -0
  263. package/dist/providers/sentry.js +45 -0
  264. package/dist/providers/sentry.js.map +1 -0
  265. package/dist/providers/shared.d.ts +15 -0
  266. package/dist/providers/shared.d.ts.map +1 -0
  267. package/dist/providers/shared.js +40 -0
  268. package/dist/providers/shared.js.map +1 -0
  269. package/dist/providers/shopify.d.ts +9 -0
  270. package/dist/providers/shopify.d.ts.map +1 -0
  271. package/dist/providers/shopify.js +38 -0
  272. package/dist/providers/shopify.js.map +1 -0
  273. package/dist/providers/standard-webhooks-protocol.d.ts +15 -0
  274. package/dist/providers/standard-webhooks-protocol.d.ts.map +1 -0
  275. package/dist/providers/standard-webhooks-protocol.js +95 -0
  276. package/dist/providers/standard-webhooks-protocol.js.map +1 -0
  277. package/dist/providers/standard-webhooks.d.ts +10 -0
  278. package/dist/providers/standard-webhooks.d.ts.map +1 -0
  279. package/dist/providers/standard-webhooks.js +13 -0
  280. package/dist/providers/standard-webhooks.js.map +1 -0
  281. package/dist/providers/stripe.d.ts +8 -0
  282. package/dist/providers/stripe.d.ts.map +1 -0
  283. package/dist/providers/stripe.js +79 -0
  284. package/dist/providers/stripe.js.map +1 -0
  285. package/dist/providers/svix.d.ts +10 -0
  286. package/dist/providers/svix.d.ts.map +1 -0
  287. package/dist/providers/svix.js +61 -0
  288. package/dist/providers/svix.js.map +1 -0
  289. package/dist/providers/vercel.d.ts +16 -0
  290. package/dist/providers/vercel.d.ts.map +1 -0
  291. package/dist/providers/vercel.js +37 -0
  292. package/dist/providers/vercel.js.map +1 -0
  293. package/dist/providers/workos.d.ts +33 -0
  294. package/dist/providers/workos.d.ts.map +1 -0
  295. package/dist/providers/workos.js +118 -0
  296. package/dist/providers/workos.js.map +1 -0
  297. package/dist/types.d.ts +69 -0
  298. package/dist/types.d.ts.map +1 -0
  299. package/dist/types.js +2 -0
  300. package/dist/types.js.map +1 -0
  301. package/package.json +200 -4
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.workosDescriptor = void 0;
4
+ const bytes_js_1 = require("../internal/bytes.cjs");
5
+ const shared_js_1 = require("./shared.cjs");
6
+ const SIGNATURE_HEADER = 'workos-signature';
7
+ const TIMESTAMP_KEY = 't';
8
+ const SIGNATURE_KEY = 'v1';
9
+ /**
10
+ * Opaque nonempty printable ASCII unknown-field value: no whitespace, commas,
11
+ * or additional equals signs. This is a bounded Hooklatch grammar, not a
12
+ * promise to support an unspecified future signature version.
13
+ */
14
+ const OPAQUE_VALUE = /^[\x21-\x2b\x2d-\x3c\x3e-\x7e]+$/;
15
+ /**
16
+ * WorkOS: `WorkOS-Signature: t=<unix milliseconds>, v1=<64 hex>`.
17
+ *
18
+ * The comma-separated field list is validated as a whole before required-field
19
+ * checks. Segments are trimmed only at their outer edges, so whitespace around
20
+ * `=` is rejected; field names are case-sensitive. `t` must appear exactly once
21
+ * and be a canonical nonnegative safe decimal integer in milliseconds (zero is
22
+ * allowed, leading zeros are not). Every `v1` must be a 32-byte hex digest in
23
+ * either case; repeated `v1` values form a Hooklatch rotation accept-set, but a
24
+ * malformed `v1` poisons the header. Unknown field names are validated as
25
+ * opaque values and then ignored.
26
+ *
27
+ * The HMAC-SHA256 covers UTF8(original `t` text + ".") concatenated with the
28
+ * exact raw body. The secret is the literal, untrimmed UTF-8 text; it is never
29
+ * Base64-decoded. Invalid-UTF-8 body handling is a Hooklatch byte-preservation
30
+ * policy, not claimed parity with SDKs that decode the body to a string.
31
+ * Identity is `timestamp = Number(t) / 1000`; freshness is enforced by core and
32
+ * is never evaluated here.
33
+ *
34
+ * This strict grammar, repeated-v1 accept-set, and millisecond identity are
35
+ * documented receiver policies, not claims of exact WorkOS SDK parity. No
36
+ * WorkOS-published signature vector is claimed; tests use synthetic anchors.
37
+ * Sources:
38
+ * - https://workos.com/docs/events/data-syncing/webhooks
39
+ * - https://raw.githubusercontent.com/workos/workos-node/ad8bff226e9b37435f0c62390318d4819f76b3d1/src/common/crypto/signature-provider.ts
40
+ */
41
+ exports.workosDescriptor = {
42
+ provider: 'workos',
43
+ decodeSecret(secret) {
44
+ return (0, shared_js_1.decodeLiteralSecret)(secret, 'WorkOS');
45
+ },
46
+ parse(headers, rawBody) {
47
+ const raw = headers.get(SIGNATURE_HEADER);
48
+ if (raw === undefined || raw.trim() === '') {
49
+ return (0, shared_js_1.failure)('missing-signature', 'No WorkOS signature header was provided.');
50
+ }
51
+ const signatures = [];
52
+ let timestampText;
53
+ let timestampCount = 0;
54
+ let unknownFields = 0;
55
+ // Validate the complete structure before any required-field decision.
56
+ for (const rawSegment of raw.split(',')) {
57
+ const segment = rawSegment.trim();
58
+ if (segment === '') {
59
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
60
+ }
61
+ // Reject missing keys, empty values, and extra equals signs.
62
+ const separator = segment.indexOf('=');
63
+ if (separator <= 0 || separator === segment.length - 1 || segment.indexOf('=', separator + 1) !== -1) {
64
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
65
+ }
66
+ const key = segment.slice(0, separator);
67
+ const value = segment.slice(separator + 1);
68
+ if (!(0, shared_js_1.isSchemeToken)(key)) {
69
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
70
+ }
71
+ if (key === TIMESTAMP_KEY) {
72
+ timestampCount += 1;
73
+ // Duplicate timestamps fail even when the values agree.
74
+ if (timestampCount > 1) {
75
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
76
+ }
77
+ if (!(0, shared_js_1.isCanonicalTimestamp)(value)) {
78
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
79
+ }
80
+ timestampText = value;
81
+ continue;
82
+ }
83
+ if (key === SIGNATURE_KEY) {
84
+ const decoded = (0, shared_js_1.decodeHexSignature)(value);
85
+ // One malformed v1 poisons the whole header, even beside a valid v1.
86
+ if (decoded === null) {
87
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
88
+ }
89
+ signatures.push(decoded);
90
+ continue;
91
+ }
92
+ // Unknown fields are structurally validated, then ignored.
93
+ if (!OPAQUE_VALUE.test(value)) {
94
+ return (0, shared_js_1.failure)('malformed-signature', 'The WorkOS signature header is malformed.');
95
+ }
96
+ unknownFields += 1;
97
+ }
98
+ // Required-field checks run only after the whole structure validated.
99
+ if (signatures.length === 0) {
100
+ return unknownFields > 0
101
+ ? (0, shared_js_1.failure)('unsupported-scheme', 'No supported WorkOS signature scheme was provided.')
102
+ : (0, shared_js_1.failure)('missing-signature', 'No WorkOS signature value was provided.');
103
+ }
104
+ if (timestampText === undefined) {
105
+ return (0, shared_js_1.failure)('missing-timestamp', 'No WorkOS timestamp was provided.');
106
+ }
107
+ const identity = {
108
+ deliveryId: null,
109
+ eventId: null,
110
+ timestamp: Number(timestampText) / 1000,
111
+ authenticatedFields: ['timestamp'],
112
+ };
113
+ return {
114
+ ok: true,
115
+ signatures,
116
+ signedContent: (0, bytes_js_1.concatBytes)((0, bytes_js_1.utf8)(`${timestampText}.`), rawBody),
117
+ identity,
118
+ };
119
+ },
120
+ };
@@ -0,0 +1,32 @@
1
+ import type { NormalizedHeaders, ParseResult } from '../internal/provider.cjs';
2
+ /**
3
+ * WorkOS: `WorkOS-Signature: t=<unix milliseconds>, v1=<64 hex>`.
4
+ *
5
+ * The comma-separated field list is validated as a whole before required-field
6
+ * checks. Segments are trimmed only at their outer edges, so whitespace around
7
+ * `=` is rejected; field names are case-sensitive. `t` must appear exactly once
8
+ * and be a canonical nonnegative safe decimal integer in milliseconds (zero is
9
+ * allowed, leading zeros are not). Every `v1` must be a 32-byte hex digest in
10
+ * either case; repeated `v1` values form a Hooklatch rotation accept-set, but a
11
+ * malformed `v1` poisons the header. Unknown field names are validated as
12
+ * opaque values and then ignored.
13
+ *
14
+ * The HMAC-SHA256 covers UTF8(original `t` text + ".") concatenated with the
15
+ * exact raw body. The secret is the literal, untrimmed UTF-8 text; it is never
16
+ * Base64-decoded. Invalid-UTF-8 body handling is a Hooklatch byte-preservation
17
+ * policy, not claimed parity with SDKs that decode the body to a string.
18
+ * Identity is `timestamp = Number(t) / 1000`; freshness is enforced by core and
19
+ * is never evaluated here.
20
+ *
21
+ * This strict grammar, repeated-v1 accept-set, and millisecond identity are
22
+ * documented receiver policies, not claims of exact WorkOS SDK parity. No
23
+ * WorkOS-published signature vector is claimed; tests use synthetic anchors.
24
+ * Sources:
25
+ * - https://workos.com/docs/events/data-syncing/webhooks
26
+ * - https://raw.githubusercontent.com/workos/workos-node/ad8bff226e9b37435f0c62390318d4819f76b3d1/src/common/crypto/signature-provider.ts
27
+ */
28
+ export declare const workosDescriptor: {
29
+ provider: "workos";
30
+ decodeSecret(secret: string): Uint8Array;
31
+ parse(headers: NormalizedHeaders, rawBody: Uint8Array): ParseResult;
32
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,68 @@
1
+ /** Contract version 1. Verification never parses or validates payload schemas. */
2
+ export type Provider = 'stripe' | 'github' | 'shopify' | 'standard-webhooks' | 'clerk' | 'svix' | 'razorpay' | 'paddle' | 'lemon-squeezy' | 'dodo-payments' | 'gitlab' | 'replicate' | 'workos' | 'sentry' | 'doppler' | 'sanity' | 'grafana' | 'polar' | 'linear' | 'vercel' | 'fal';
3
+ export type HeaderInput = Headers | Readonly<Record<string, string | readonly string[] | undefined>> | readonly (readonly [string, string])[];
4
+ export interface WebhookRequest {
5
+ readonly rawBody: Uint8Array;
6
+ readonly headers: HeaderInput;
7
+ }
8
+ export type GrafanaOptions = {
9
+ readonly mode: 'body';
10
+ readonly signatureHeader?: string;
11
+ readonly timestampHeader?: never;
12
+ } | {
13
+ readonly mode: 'timestamped';
14
+ readonly signatureHeader?: string;
15
+ readonly timestampHeader: string;
16
+ };
17
+ export interface PolarOptions {
18
+ readonly secretMode?: 'current' | 'legacy';
19
+ }
20
+ interface CommonVerifyOptions {
21
+ readonly toleranceSeconds?: number;
22
+ readonly now?: () => number;
23
+ readonly maxBodyBytes?: number;
24
+ }
25
+ export type FalVerifyOptions = CommonVerifyOptions & {
26
+ readonly provider: 'fal';
27
+ readonly publicKeys: readonly Uint8Array[];
28
+ readonly expectedUserId: string;
29
+ readonly secrets?: never;
30
+ readonly providerOptions?: never;
31
+ };
32
+ export type VerifyOptions = FalVerifyOptions | (CommonVerifyOptions & {
33
+ readonly secrets: readonly string[];
34
+ } & ({
35
+ readonly provider: Exclude<Provider, 'grafana' | 'polar' | 'fal'>;
36
+ readonly providerOptions?: never;
37
+ } | {
38
+ readonly provider: 'grafana';
39
+ readonly providerOptions: GrafanaOptions;
40
+ } | {
41
+ readonly provider: 'polar';
42
+ readonly providerOptions?: PolarOptions;
43
+ }));
44
+ export type IdentityField = 'deliveryId' | 'eventId' | 'timestamp';
45
+ export interface EventIdentity {
46
+ readonly deliveryId: string | null;
47
+ readonly eventId: string | null;
48
+ readonly timestamp: number | null;
49
+ readonly authenticatedFields: readonly IdentityField[];
50
+ }
51
+ export type VerificationFailureReason = 'missing-signature' | 'malformed-signature' | 'unsupported-scheme' | 'invalid-signature' | 'missing-identity' | 'missing-timestamp' | 'timestamp-expired' | 'timestamp-future' | 'body-too-large';
52
+ export interface FailureDetails {
53
+ readonly ok: false;
54
+ readonly reason: VerificationFailureReason;
55
+ readonly message: string;
56
+ }
57
+ export interface VerificationSuccess {
58
+ readonly ok: true;
59
+ readonly provider: Provider;
60
+ readonly rawBody: Uint8Array;
61
+ readonly identity: EventIdentity;
62
+ }
63
+ export interface VerificationFailure extends FailureDetails {
64
+ readonly provider: Provider;
65
+ }
66
+ export type VerificationResult = VerificationSuccess | VerificationFailure;
67
+ export type HooklatchErrorCode = 'unknown-provider' | 'missing-secrets' | 'invalid-secret' | 'invalid-options' | 'invalid-input' | 'body-consumed' | 'body-read-failed' | 'crypto-unavailable' | 'internal';
68
+ export {};
@@ -0,0 +1,86 @@
1
+ import type { Provider } from '../types.js';
2
+ export type Framework = 'express' | 'nextjs' | 'hono' | 'cloudflare';
3
+ export declare const FRAMEWORKS: readonly ["express", "nextjs", "hono", "cloudflare"];
4
+ export type GrafanaMode = 'body' | 'timestamped';
5
+ export type PolarSecretMode = 'current' | 'legacy';
6
+ export interface GrafanaCliOptions {
7
+ readonly mode: GrafanaMode;
8
+ readonly signatureHeader?: string;
9
+ readonly timestampHeader?: string;
10
+ }
11
+ export interface PolarCliOptions {
12
+ readonly secretMode: PolarSecretMode;
13
+ }
14
+ export interface FalCliOptions {
15
+ readonly publicKeyEnv: string;
16
+ readonly expectedUserEnv: string;
17
+ }
18
+ export type ProviderCliOptions = {
19
+ readonly provider: 'grafana';
20
+ readonly options: GrafanaCliOptions;
21
+ } | {
22
+ readonly provider: 'polar';
23
+ readonly options: PolarCliOptions;
24
+ } | {
25
+ readonly provider: 'fal';
26
+ readonly options: FalCliOptions;
27
+ };
28
+ /** Raw flag values collected by the argument scanner, before provider rules. */
29
+ export interface RawProviderFlags {
30
+ readonly grafanaMode: string | undefined;
31
+ readonly signatureHeader: string | undefined;
32
+ readonly timestampHeader: string | undefined;
33
+ readonly polarSecretMode: string | undefined;
34
+ readonly publicKeyEnv?: string | undefined;
35
+ readonly expectedUserEnv?: string | undefined;
36
+ }
37
+ export type ProviderCliOptionsResult = {
38
+ readonly kind: 'none';
39
+ } | {
40
+ readonly kind: 'options';
41
+ readonly options: ProviderCliOptions;
42
+ } | {
43
+ readonly kind: 'error';
44
+ readonly message: string;
45
+ };
46
+ interface CommandFields {
47
+ readonly framework: Framework;
48
+ readonly out: string;
49
+ readonly bodyLimit: number;
50
+ readonly dryRun: boolean;
51
+ }
52
+ export type WebhookCommand = CommandFields & ({
53
+ readonly provider: 'fal';
54
+ readonly publicKeyEnv: string;
55
+ readonly expectedUserEnv: string;
56
+ readonly secretEnv?: never;
57
+ readonly providerOptions?: never;
58
+ } | {
59
+ readonly provider: Exclude<Provider, 'fal'>;
60
+ readonly secretEnv: string;
61
+ readonly publicKeyEnv?: never;
62
+ readonly expectedUserEnv?: never;
63
+ readonly providerOptions?: Exclude<ProviderCliOptions, {
64
+ readonly provider: 'fal';
65
+ }>;
66
+ });
67
+ export type ParseResult = {
68
+ readonly kind: 'help';
69
+ } | {
70
+ readonly kind: 'command';
71
+ readonly command: WebhookCommand;
72
+ } | {
73
+ readonly kind: 'error';
74
+ readonly exitCode: 2;
75
+ readonly message: string;
76
+ };
77
+ export declare const HELP_TEXT = "Usage: hooklatch init webhook --provider <id> --framework <id> [options]\n\nGenerate one TypeScript webhook endpoint file from an existing Hooklatch adapter.\n\nRequired:\n --provider <id> Implemented provider id.\n --framework <id> One of: express, nextjs, hono, cloudflare.\n\nOptions:\n --out <dir> Output directory (default: hooklatch).\n --secret-env <NAME> Environment variable holding the secret (default by provider).\n --body-limit <bytes> Positive safe integer body limit (default: 1048576).\n --grafana-mode <mode> Grafana only: body or timestamped (required for grafana).\n --signature-header <NAME>\n Grafana only: RFC 9110 header token (default x-grafana-alerting-signature).\n --timestamp-header <NAME>\n Grafana only: required with timestamped; forbidden with body.\n --polar-secret-mode <mode>\n Polar only: current (default) or legacy.\n --public-key-env <NAME>\n Fal only: env var holding comma-separated Base64url public keys (default FAL_WEBHOOK_PUBLIC_KEYS).\n --expected-user-env <NAME>\n Fal only: env var holding the expected user id (default FAL_WEBHOOK_USER_ID).\n --dry-run Print the target path and contents without writing.\n -h, --help Show this help.\n\nExit codes:\n 0 Success, dry run, or help.\n 1 Unexpected generation or I/O error.\n 2 Invalid arguments or unsafe path.\n 3 Target file already exists.\n";
78
+ /**
79
+ * Apply provider-specific flag rules. Registration stays coordinator-owned:
80
+ * a provider that is not yet in the public registry is rejected by
81
+ * `parseArgs` before this function runs.
82
+ */
83
+ export declare function buildProviderCliOptions(provider: string, flags: RawProviderFlags): ProviderCliOptionsResult;
84
+ export declare function parseArgs(argv: readonly string[]): ParseResult;
85
+ export {};
86
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}