@xtandard/webhooks 0.1.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 (279) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +315 -0
  3. package/bin/xtandard-webhooks.mjs +3 -0
  4. package/dist/basic-BIW3Rvuz.cjs +199 -0
  5. package/dist/basic-BIW3Rvuz.cjs.map +1 -0
  6. package/dist/basic-DKk0Xfuu.mjs +176 -0
  7. package/dist/basic-DKk0Xfuu.mjs.map +1 -0
  8. package/dist/chunk-D7D4PA-g.mjs +13 -0
  9. package/dist/cli.cjs +655 -0
  10. package/dist/cli.cjs.map +1 -0
  11. package/dist/cli.d.cts +42 -0
  12. package/dist/cli.d.mts +42 -0
  13. package/dist/cli.mjs +653 -0
  14. package/dist/cli.mjs.map +1 -0
  15. package/dist/contract-8h-Azxa5.d.cts +71 -0
  16. package/dist/contract-9XpcwcCn.mjs +22 -0
  17. package/dist/contract-9XpcwcCn.mjs.map +1 -0
  18. package/dist/contract-B2d5dNU3.cjs +33 -0
  19. package/dist/contract-B2d5dNU3.cjs.map +1 -0
  20. package/dist/contract-BEhDcd_5.mjs +28 -0
  21. package/dist/contract-BEhDcd_5.mjs.map +1 -0
  22. package/dist/contract-Bf1qguwt.cjs +57 -0
  23. package/dist/contract-Bf1qguwt.cjs.map +1 -0
  24. package/dist/contract-Bnb3fgRJ.d.cts +177 -0
  25. package/dist/contract-C2r2Xzwp.d.mts +46 -0
  26. package/dist/contract-CiPskNvS.d.cts +46 -0
  27. package/dist/contract-DhQ4JjGG.d.mts +71 -0
  28. package/dist/contract-T1kcZNdG.d.mts +177 -0
  29. package/dist/contract-lETlIuXo.d.cts +30 -0
  30. package/dist/contract-lETlIuXo.d.mts +30 -0
  31. package/dist/core-CMpnmI5Q.mjs +1605 -0
  32. package/dist/core-CMpnmI5Q.mjs.map +1 -0
  33. package/dist/core-DT4ppWh8.d.mts +502 -0
  34. package/dist/core-KJawHjFF.d.cts +502 -0
  35. package/dist/core-ZGhH6Vs2.cjs +1790 -0
  36. package/dist/core-ZGhH6Vs2.cjs.map +1 -0
  37. package/dist/core.cjs +8 -0
  38. package/dist/core.d.cts +2 -0
  39. package/dist/core.d.mts +2 -0
  40. package/dist/core.mjs +2 -0
  41. package/dist/create-fetch-handler-BIdk9P30.mjs +1724 -0
  42. package/dist/create-fetch-handler-BIdk9P30.mjs.map +1 -0
  43. package/dist/create-fetch-handler-CmooujQo.cjs +1771 -0
  44. package/dist/create-fetch-handler-CmooujQo.cjs.map +1 -0
  45. package/dist/create-fetch-handler-Dlkhustu.d.cts +162 -0
  46. package/dist/create-fetch-handler-jy3hy5nZ.d.mts +162 -0
  47. package/dist/dispatcher-B0xTEHt1.cjs +212 -0
  48. package/dist/dispatcher-B0xTEHt1.cjs.map +1 -0
  49. package/dist/dispatcher-Coubwrka.mjs +196 -0
  50. package/dist/dispatcher-Coubwrka.mjs.map +1 -0
  51. package/dist/entry-auth-basic.cjs +5 -0
  52. package/dist/entry-auth-basic.d.cts +83 -0
  53. package/dist/entry-auth-basic.d.mts +83 -0
  54. package/dist/entry-auth-basic.mjs +2 -0
  55. package/dist/entry-auth-delegated.cjs +28 -0
  56. package/dist/entry-auth-delegated.cjs.map +1 -0
  57. package/dist/entry-auth-delegated.d.cts +36 -0
  58. package/dist/entry-auth-delegated.d.mts +36 -0
  59. package/dist/entry-auth-delegated.mjs +27 -0
  60. package/dist/entry-auth-delegated.mjs.map +1 -0
  61. package/dist/entry-auth-none.cjs +4 -0
  62. package/dist/entry-auth-none.d.cts +25 -0
  63. package/dist/entry-auth-none.d.mts +25 -0
  64. package/dist/entry-auth-none.mjs +2 -0
  65. package/dist/entry-authorization-delegated.cjs +27 -0
  66. package/dist/entry-authorization-delegated.cjs.map +1 -0
  67. package/dist/entry-authorization-delegated.d.cts +31 -0
  68. package/dist/entry-authorization-delegated.d.mts +31 -0
  69. package/dist/entry-authorization-delegated.mjs +26 -0
  70. package/dist/entry-authorization-delegated.mjs.map +1 -0
  71. package/dist/entry-authorization-none.cjs +3 -0
  72. package/dist/entry-authorization-none.d.cts +18 -0
  73. package/dist/entry-authorization-none.d.mts +18 -0
  74. package/dist/entry-authorization-none.mjs +2 -0
  75. package/dist/entry-authorization-roles.cjs +6 -0
  76. package/dist/entry-authorization-roles.d.cts +65 -0
  77. package/dist/entry-authorization-roles.d.mts +65 -0
  78. package/dist/entry-authorization-roles.mjs +2 -0
  79. package/dist/entry-bun.cjs +24 -0
  80. package/dist/entry-bun.cjs.map +1 -0
  81. package/dist/entry-bun.d.cts +8 -0
  82. package/dist/entry-bun.d.mts +8 -0
  83. package/dist/entry-bun.mjs +23 -0
  84. package/dist/entry-bun.mjs.map +1 -0
  85. package/dist/entry-drizzle-mysql.cjs +20 -0
  86. package/dist/entry-drizzle-mysql.cjs.map +1 -0
  87. package/dist/entry-drizzle-mysql.d.cts +27 -0
  88. package/dist/entry-drizzle-mysql.d.mts +27 -0
  89. package/dist/entry-drizzle-mysql.mjs +19 -0
  90. package/dist/entry-drizzle-mysql.mjs.map +1 -0
  91. package/dist/entry-drizzle-pg.cjs +21 -0
  92. package/dist/entry-drizzle-pg.cjs.map +1 -0
  93. package/dist/entry-drizzle-pg.d.cts +26 -0
  94. package/dist/entry-drizzle-pg.d.mts +26 -0
  95. package/dist/entry-drizzle-pg.mjs +20 -0
  96. package/dist/entry-drizzle-pg.mjs.map +1 -0
  97. package/dist/entry-drizzle-sqlite.cjs +21 -0
  98. package/dist/entry-drizzle-sqlite.cjs.map +1 -0
  99. package/dist/entry-drizzle-sqlite.d.cts +23 -0
  100. package/dist/entry-drizzle-sqlite.d.mts +23 -0
  101. package/dist/entry-drizzle-sqlite.mjs +20 -0
  102. package/dist/entry-drizzle-sqlite.mjs.map +1 -0
  103. package/dist/entry-elysia.cjs +125 -0
  104. package/dist/entry-elysia.cjs.map +1 -0
  105. package/dist/entry-elysia.d.cts +1017 -0
  106. package/dist/entry-elysia.d.mts +1017 -0
  107. package/dist/entry-elysia.mjs +123 -0
  108. package/dist/entry-elysia.mjs.map +1 -0
  109. package/dist/entry-express.cjs +57 -0
  110. package/dist/entry-express.cjs.map +1 -0
  111. package/dist/entry-express.d.cts +15 -0
  112. package/dist/entry-express.d.mts +15 -0
  113. package/dist/entry-express.mjs +56 -0
  114. package/dist/entry-express.mjs.map +1 -0
  115. package/dist/entry-hono.cjs +35 -0
  116. package/dist/entry-hono.cjs.map +1 -0
  117. package/dist/entry-hono.d.cts +16 -0
  118. package/dist/entry-hono.d.mts +16 -0
  119. package/dist/entry-hono.mjs +34 -0
  120. package/dist/entry-hono.mjs.map +1 -0
  121. package/dist/entry-hooks-log.cjs +22 -0
  122. package/dist/entry-hooks-log.cjs.map +1 -0
  123. package/dist/entry-hooks-log.d.cts +23 -0
  124. package/dist/entry-hooks-log.d.mts +23 -0
  125. package/dist/entry-hooks-log.mjs +21 -0
  126. package/dist/entry-hooks-log.mjs.map +1 -0
  127. package/dist/entry-storage-cloudflare-kv.cjs +47 -0
  128. package/dist/entry-storage-cloudflare-kv.cjs.map +1 -0
  129. package/dist/entry-storage-cloudflare-kv.d.cts +42 -0
  130. package/dist/entry-storage-cloudflare-kv.d.mts +42 -0
  131. package/dist/entry-storage-cloudflare-kv.mjs +46 -0
  132. package/dist/entry-storage-cloudflare-kv.mjs.map +1 -0
  133. package/dist/entry-storage-drizzle.cjs +78 -0
  134. package/dist/entry-storage-drizzle.cjs.map +1 -0
  135. package/dist/entry-storage-drizzle.d.cts +30 -0
  136. package/dist/entry-storage-drizzle.d.mts +30 -0
  137. package/dist/entry-storage-drizzle.mjs +77 -0
  138. package/dist/entry-storage-drizzle.mjs.map +1 -0
  139. package/dist/entry-storage-file.cjs +4 -0
  140. package/dist/entry-storage-file.d.cts +30 -0
  141. package/dist/entry-storage-file.d.mts +30 -0
  142. package/dist/entry-storage-file.mjs +2 -0
  143. package/dist/entry-storage-libsql.cjs +3 -0
  144. package/dist/entry-storage-libsql.d.cts +48 -0
  145. package/dist/entry-storage-libsql.d.mts +48 -0
  146. package/dist/entry-storage-libsql.mjs +2 -0
  147. package/dist/entry-storage-memory.cjs +3 -0
  148. package/dist/entry-storage-memory.d.cts +2 -0
  149. package/dist/entry-storage-memory.d.mts +2 -0
  150. package/dist/entry-storage-memory.mjs +2 -0
  151. package/dist/entry-storage-mongodb.cjs +3 -0
  152. package/dist/entry-storage-mongodb.d.cts +55 -0
  153. package/dist/entry-storage-mongodb.d.mts +55 -0
  154. package/dist/entry-storage-mongodb.mjs +2 -0
  155. package/dist/entry-storage-postgres.cjs +3 -0
  156. package/dist/entry-storage-postgres.d.cts +62 -0
  157. package/dist/entry-storage-postgres.d.mts +62 -0
  158. package/dist/entry-storage-postgres.mjs +2 -0
  159. package/dist/entry-storage-redis.cjs +4 -0
  160. package/dist/entry-storage-redis.d.cts +77 -0
  161. package/dist/entry-storage-redis.d.mts +77 -0
  162. package/dist/entry-storage-redis.mjs +2 -0
  163. package/dist/entry-storage-sqlite.cjs +3 -0
  164. package/dist/entry-storage-sqlite.d.cts +36 -0
  165. package/dist/entry-storage-sqlite.d.mts +36 -0
  166. package/dist/entry-storage-sqlite.mjs +2 -0
  167. package/dist/entry-storage-unstorage.cjs +42 -0
  168. package/dist/entry-storage-unstorage.cjs.map +1 -0
  169. package/dist/entry-storage-unstorage.d.cts +29 -0
  170. package/dist/entry-storage-unstorage.d.mts +29 -0
  171. package/dist/entry-storage-unstorage.mjs +41 -0
  172. package/dist/entry-storage-unstorage.mjs.map +1 -0
  173. package/dist/file-COBYZA4Q.cjs +148 -0
  174. package/dist/file-COBYZA4Q.cjs.map +1 -0
  175. package/dist/file-fi02eFHk.mjs +131 -0
  176. package/dist/file-fi02eFHk.mjs.map +1 -0
  177. package/dist/index.cjs +123 -0
  178. package/dist/index.cjs.map +1 -0
  179. package/dist/index.d.cts +368 -0
  180. package/dist/index.d.mts +366 -0
  181. package/dist/index.mjs +61 -0
  182. package/dist/index.mjs.map +1 -0
  183. package/dist/keys-Byyj4quQ.mjs +111 -0
  184. package/dist/keys-Byyj4quQ.mjs.map +1 -0
  185. package/dist/keys-FiKpaVHX.cjs +302 -0
  186. package/dist/keys-FiKpaVHX.cjs.map +1 -0
  187. package/dist/libsql-bpVi0bXN.mjs +113 -0
  188. package/dist/libsql-bpVi0bXN.mjs.map +1 -0
  189. package/dist/libsql-pPJEo1e4.cjs +124 -0
  190. package/dist/libsql-pPJEo1e4.cjs.map +1 -0
  191. package/dist/memory-8Ef-PL5a.cjs +137 -0
  192. package/dist/memory-8Ef-PL5a.cjs.map +1 -0
  193. package/dist/memory-BMsSSwqn.mjs +127 -0
  194. package/dist/memory-BMsSSwqn.mjs.map +1 -0
  195. package/dist/memory-FnMJWCmB.d.cts +28 -0
  196. package/dist/memory-qIvANEs_.d.mts +28 -0
  197. package/dist/mongodb-Cy8yo0uk.cjs +108 -0
  198. package/dist/mongodb-Cy8yo0uk.cjs.map +1 -0
  199. package/dist/mongodb-Ddaq9mml.mjs +97 -0
  200. package/dist/mongodb-Ddaq9mml.mjs.map +1 -0
  201. package/dist/none-BnZtaGNJ.mjs +23 -0
  202. package/dist/none-BnZtaGNJ.mjs.map +1 -0
  203. package/dist/none-CAsxCOWN.cjs +49 -0
  204. package/dist/none-CAsxCOWN.cjs.map +1 -0
  205. package/dist/none-CZVrfnmF.cjs +33 -0
  206. package/dist/none-CZVrfnmF.cjs.map +1 -0
  207. package/dist/none-GhVIoh_s.mjs +33 -0
  208. package/dist/none-GhVIoh_s.mjs.map +1 -0
  209. package/dist/postgres-C8WbchFa.cjs +134 -0
  210. package/dist/postgres-C8WbchFa.cjs.map +1 -0
  211. package/dist/postgres-c3pAhmhr.mjs +123 -0
  212. package/dist/postgres-c3pAhmhr.mjs.map +1 -0
  213. package/dist/react.css +1 -0
  214. package/dist/react.js +31465 -0
  215. package/dist/receiver.cjs +43 -0
  216. package/dist/receiver.cjs.map +1 -0
  217. package/dist/receiver.d.cts +36 -0
  218. package/dist/receiver.d.mts +36 -0
  219. package/dist/receiver.mjs +40 -0
  220. package/dist/receiver.mjs.map +1 -0
  221. package/dist/redis-CFJkuSgB.cjs +270 -0
  222. package/dist/redis-CFJkuSgB.cjs.map +1 -0
  223. package/dist/redis-CvLi0KF7.mjs +254 -0
  224. package/dist/redis-CvLi0KF7.mjs.map +1 -0
  225. package/dist/roles-D0G9XqBq.cjs +128 -0
  226. package/dist/roles-D0G9XqBq.cjs.map +1 -0
  227. package/dist/roles-vp361lTk.mjs +99 -0
  228. package/dist/roles-vp361lTk.mjs.map +1 -0
  229. package/dist/schema-mo__wv4P.d.cts +233 -0
  230. package/dist/schema-mo__wv4P.d.mts +233 -0
  231. package/dist/schema.cjs +13 -0
  232. package/dist/schema.cjs.map +1 -0
  233. package/dist/schema.d.cts +2 -0
  234. package/dist/schema.d.mts +2 -0
  235. package/dist/schema.mjs +11 -0
  236. package/dist/schema.mjs.map +1 -0
  237. package/dist/signing.cjs +162 -0
  238. package/dist/signing.cjs.map +1 -0
  239. package/dist/signing.d.cts +73 -0
  240. package/dist/signing.d.mts +73 -0
  241. package/dist/signing.mjs +156 -0
  242. package/dist/signing.mjs.map +1 -0
  243. package/dist/sqlite-Cmqnrjes.mjs +67 -0
  244. package/dist/sqlite-Cmqnrjes.mjs.map +1 -0
  245. package/dist/sqlite-Dcufk0x3.cjs +78 -0
  246. package/dist/sqlite-Dcufk0x3.cjs.map +1 -0
  247. package/dist/table-Ce3Tzwqs.d.cts +11 -0
  248. package/dist/table-Ce3Tzwqs.d.mts +11 -0
  249. package/dist/testing.cjs +134 -0
  250. package/dist/testing.cjs.map +1 -0
  251. package/dist/testing.d.cts +80 -0
  252. package/dist/testing.d.mts +80 -0
  253. package/dist/testing.mjs +131 -0
  254. package/dist/testing.mjs.map +1 -0
  255. package/dist/types-react/react.d.ts +98 -0
  256. package/dist/types-react/schema.d.ts +229 -0
  257. package/dist/types-react/ui/App.d.ts +22 -0
  258. package/dist/types-react/ui/api.d.ts +97 -0
  259. package/dist/types-react/ui/components/JsonCodeEditor.d.ts +12 -0
  260. package/dist/types-react/ui/components/ThemeToggle.d.ts +2 -0
  261. package/dist/types-react/ui/components/Toast.d.ts +16 -0
  262. package/dist/types-react/ui/components/primitives.d.ts +50 -0
  263. package/dist/types-react/ui/components/ui-bits.d.ts +22 -0
  264. package/dist/types-react/ui/components/webhook-bits.d.ts +51 -0
  265. package/dist/types-react/ui/lib/format.d.ts +39 -0
  266. package/dist/types-react/ui/lib/nav-guard.d.ts +20 -0
  267. package/dist/types-react/ui/lib/utils.d.ts +3 -0
  268. package/dist/types-react/ui/theme.d.ts +12 -0
  269. package/dist/types-react/ui/types.d.ts +80 -0
  270. package/dist/types-react/ui/views/AuditView.d.ts +6 -0
  271. package/dist/types-react/ui/views/DeliveriesView.d.ts +12 -0
  272. package/dist/types-react/ui/views/EndpointsView.d.ts +11 -0
  273. package/dist/types-react/ui/views/EventTypesView.d.ts +11 -0
  274. package/dist/types-react/ui/views/MessagesView.d.ts +10 -0
  275. package/dist/types-react/ui/views/OverviewView.d.ts +12 -0
  276. package/dist/ui/assets/index-B0eoQX2U.css +1 -0
  277. package/dist/ui/assets/index-S5t_CLOe.js +209 -0
  278. package/dist/ui/index.html +14 -0
  279. package/package.json +487 -0
@@ -0,0 +1,42 @@
1
+ import { o as WebhooksStorage } from "./contract-8h-Azxa5.cjs";
2
+
3
+ //#region src/storage/cloudflare-kv.d.ts
4
+ /** The subset of the Workers `KVNamespace` binding this adapter uses. */
5
+ interface KVNamespaceLike {
6
+ get(key: string, type?: "text"): Promise<string | null>;
7
+ put(key: string, value: string): Promise<void>;
8
+ delete(key: string): Promise<void>;
9
+ list(options?: {
10
+ prefix?: string;
11
+ cursor?: string;
12
+ limit?: number;
13
+ }): Promise<{
14
+ keys: Array<{
15
+ name: string;
16
+ }>;
17
+ list_complete: boolean;
18
+ cursor?: string;
19
+ }>;
20
+ }
21
+ /** Options for {@link createCloudflareKvStorage}. */
22
+ interface CloudflareKvStorageOptions {
23
+ /** The KV namespace binding (e.g. `env.WEBHOOKS`). */
24
+ namespace: KVNamespaceLike;
25
+ /** Optional key namespace prepended to every key, joined with `:`. */
26
+ prefix?: string;
27
+ }
28
+ /** A {@link WebhooksStorage} backed by a Cloudflare KV namespace binding. */
29
+ type CloudflareKvWebhooksStorage = WebhooksStorage;
30
+ /**
31
+ * Create a Cloudflare KV–backed {@link WebhooksStorage} from a `KVNamespace` binding.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { createCloudflareKvStorage } from "@xtandard/webhooks/storage/cloudflare-kv";
36
+ * const storage = createCloudflareKvStorage({ namespace: env.WEBHOOKS });
37
+ * ```
38
+ */
39
+ declare function createCloudflareKvStorage(options: CloudflareKvStorageOptions): CloudflareKvWebhooksStorage;
40
+ //#endregion
41
+ export { CloudflareKvStorageOptions, CloudflareKvWebhooksStorage, KVNamespaceLike, createCloudflareKvStorage };
42
+ //# sourceMappingURL=entry-storage-cloudflare-kv.d.cts.map
@@ -0,0 +1,42 @@
1
+ import { o as WebhooksStorage } from "./contract-DhQ4JjGG.mjs";
2
+
3
+ //#region src/storage/cloudflare-kv.d.ts
4
+ /** The subset of the Workers `KVNamespace` binding this adapter uses. */
5
+ interface KVNamespaceLike {
6
+ get(key: string, type?: "text"): Promise<string | null>;
7
+ put(key: string, value: string): Promise<void>;
8
+ delete(key: string): Promise<void>;
9
+ list(options?: {
10
+ prefix?: string;
11
+ cursor?: string;
12
+ limit?: number;
13
+ }): Promise<{
14
+ keys: Array<{
15
+ name: string;
16
+ }>;
17
+ list_complete: boolean;
18
+ cursor?: string;
19
+ }>;
20
+ }
21
+ /** Options for {@link createCloudflareKvStorage}. */
22
+ interface CloudflareKvStorageOptions {
23
+ /** The KV namespace binding (e.g. `env.WEBHOOKS`). */
24
+ namespace: KVNamespaceLike;
25
+ /** Optional key namespace prepended to every key, joined with `:`. */
26
+ prefix?: string;
27
+ }
28
+ /** A {@link WebhooksStorage} backed by a Cloudflare KV namespace binding. */
29
+ type CloudflareKvWebhooksStorage = WebhooksStorage;
30
+ /**
31
+ * Create a Cloudflare KV–backed {@link WebhooksStorage} from a `KVNamespace` binding.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { createCloudflareKvStorage } from "@xtandard/webhooks/storage/cloudflare-kv";
36
+ * const storage = createCloudflareKvStorage({ namespace: env.WEBHOOKS });
37
+ * ```
38
+ */
39
+ declare function createCloudflareKvStorage(options: CloudflareKvStorageOptions): CloudflareKvWebhooksStorage;
40
+ //#endregion
41
+ export { CloudflareKvStorageOptions, CloudflareKvWebhooksStorage, KVNamespaceLike, createCloudflareKvStorage };
42
+ //# sourceMappingURL=entry-storage-cloudflare-kv.d.mts.map
@@ -0,0 +1,46 @@
1
+ //#region src/storage/cloudflare-kv.ts
2
+ /**
3
+ * Create a Cloudflare KV–backed {@link WebhooksStorage} from a `KVNamespace` binding.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { createCloudflareKvStorage } from "@xtandard/webhooks/storage/cloudflare-kv";
8
+ * const storage = createCloudflareKvStorage({ namespace: env.WEBHOOKS });
9
+ * ```
10
+ */
11
+ function createCloudflareKvStorage(options) {
12
+ const { namespace } = options;
13
+ const fullPrefix = options.prefix ? `${options.prefix}:` : "";
14
+ const toKey = (key) => `${fullPrefix}${key}`;
15
+ const fromKey = (key) => fullPrefix && key.startsWith(fullPrefix) ? key.slice(fullPrefix.length) : key;
16
+ return {
17
+ async getItem(key) {
18
+ const raw = await namespace.get(toKey(key), "text");
19
+ return raw === null ? null : JSON.parse(raw);
20
+ },
21
+ async setItem(key, value) {
22
+ await namespace.put(toKey(key), JSON.stringify(value));
23
+ },
24
+ async removeItem(key) {
25
+ await namespace.delete(toKey(key));
26
+ },
27
+ async getKeys(prefix) {
28
+ const match = toKey(prefix);
29
+ const out = [];
30
+ let cursor;
31
+ do {
32
+ const page = await namespace.list({
33
+ prefix: match,
34
+ ...cursor ? { cursor } : {}
35
+ });
36
+ for (const k of page.keys) out.push(fromKey(k.name));
37
+ cursor = page.list_complete ? void 0 : page.cursor;
38
+ } while (cursor);
39
+ return out;
40
+ }
41
+ };
42
+ }
43
+ //#endregion
44
+ export { createCloudflareKvStorage };
45
+
46
+ //# sourceMappingURL=entry-storage-cloudflare-kv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-storage-cloudflare-kv.mjs","names":[],"sources":["../src/storage/cloudflare-kv.ts"],"sourcesContent":["/**\n * Cloudflare Workers KV storage adapter. It wraps a `KVNamespace` **binding** —\n * the object Workers exposes on `env.MY_KV` — so it works in production Workers,\n * in local dev via `wrangler dev` / [Miniflare](https://miniflare.dev), and in\n * tests against any object that satisfies the small {@link KVNamespaceLike}\n * surface. There is **no npm peer dependency**: the binding is provided by the\n * runtime, so this adapter only needs the structural type.\n *\n * KV is eventually consistent and has a ~25 MB per-value limit and list\n * pagination — acceptable for a webhooks control plane at library scale. An\n * optional `prefix` namespaces every key (joined with `:`) and is stripped from\n * {@link CloudflareKvWebhooksStorage.getKeys} results, so several deployments\n * can share one namespace.\n *\n * **Dispatcher note:** Workers have no long-lived process, so the delivery\n * dispatcher cannot run its own interval loop. Configure a\n * [cron trigger](https://developers.cloudflare.com/workers/configuration/cron-triggers/)\n * whose `scheduled` handler calls the dispatcher's `tick()` to drive due\n * deliveries.\n *\n * ```ts\n * import { createCloudflareKvStorage } from \"@xtandard/webhooks/storage/cloudflare-kv\";\n *\n * export default {\n * async fetch(req: Request, env: { WEBHOOKS: KVNamespace }) {\n * const storage = createCloudflareKvStorage({ namespace: env.WEBHOOKS, prefix: \"prod\" });\n * // …build the webhooks core over `storage`…\n * },\n * };\n * ```\n *\n * @module\n */\n\nimport type { WebhooksStorage } from \"./contract.ts\";\n\n/** The subset of the Workers `KVNamespace` binding this adapter uses. */\nexport interface KVNamespaceLike {\n get(key: string, type?: \"text\"): Promise<string | null>;\n put(key: string, value: string): Promise<void>;\n delete(key: string): Promise<void>;\n list(options?: {\n prefix?: string;\n cursor?: string;\n limit?: number;\n }): Promise<{ keys: Array<{ name: string }>; list_complete: boolean; cursor?: string }>;\n}\n\n/** Options for {@link createCloudflareKvStorage}. */\nexport interface CloudflareKvStorageOptions {\n /** The KV namespace binding (e.g. `env.WEBHOOKS`). */\n namespace: KVNamespaceLike;\n /** Optional key namespace prepended to every key, joined with `:`. */\n prefix?: string;\n}\n\n/** A {@link WebhooksStorage} backed by a Cloudflare KV namespace binding. */\nexport type CloudflareKvWebhooksStorage = WebhooksStorage;\n\n/**\n * Create a Cloudflare KV–backed {@link WebhooksStorage} from a `KVNamespace` binding.\n *\n * @example\n * ```ts\n * import { createCloudflareKvStorage } from \"@xtandard/webhooks/storage/cloudflare-kv\";\n * const storage = createCloudflareKvStorage({ namespace: env.WEBHOOKS });\n * ```\n */\nexport function createCloudflareKvStorage(\n options: CloudflareKvStorageOptions,\n): CloudflareKvWebhooksStorage {\n const { namespace } = options;\n const fullPrefix = options.prefix ? `${options.prefix}:` : \"\";\n const toKey = (key: string): string => `${fullPrefix}${key}`;\n const fromKey = (key: string): string =>\n fullPrefix && key.startsWith(fullPrefix) ? key.slice(fullPrefix.length) : key;\n\n return {\n async getItem<T>(key: string): Promise<T | null> {\n const raw = await namespace.get(toKey(key), \"text\");\n return raw === null ? null : (JSON.parse(raw) as T);\n },\n\n async setItem<T>(key: string, value: T): Promise<void> {\n await namespace.put(toKey(key), JSON.stringify(value));\n },\n\n async removeItem(key: string): Promise<void> {\n await namespace.delete(toKey(key));\n },\n\n async getKeys(prefix: string): Promise<string[]> {\n const match = toKey(prefix);\n const out: string[] = [];\n let cursor: string | undefined;\n // KV list is paginated; page through until complete.\n do {\n const page = await namespace.list({ prefix: match, ...(cursor ? { cursor } : {}) });\n for (const k of page.keys) out.push(fromKey(k.name));\n cursor = page.list_complete ? undefined : page.cursor;\n } while (cursor);\n return out;\n },\n } satisfies CloudflareKvWebhooksStorage;\n}\n"],"mappings":";;;;;;;;;;AAoEA,SAAgB,0BACd,SAC6B;CAC7B,MAAM,EAAE,cAAc;CACtB,MAAM,aAAa,QAAQ,SAAS,GAAG,QAAQ,OAAO,KAAK;CAC3D,MAAM,SAAS,QAAwB,GAAG,aAAa;CACvD,MAAM,WAAW,QACf,cAAc,IAAI,WAAW,UAAU,IAAI,IAAI,MAAM,WAAW,MAAM,IAAI;CAE5E,OAAO;EACL,MAAM,QAAW,KAAgC;GAC/C,MAAM,MAAM,MAAM,UAAU,IAAI,MAAM,GAAG,GAAG,MAAM;GAClD,OAAO,QAAQ,OAAO,OAAQ,KAAK,MAAM,GAAG;EAC9C;EAEA,MAAM,QAAW,KAAa,OAAyB;GACrD,MAAM,UAAU,IAAI,MAAM,GAAG,GAAG,KAAK,UAAU,KAAK,CAAC;EACvD;EAEA,MAAM,WAAW,KAA4B;GAC3C,MAAM,UAAU,OAAO,MAAM,GAAG,CAAC;EACnC;EAEA,MAAM,QAAQ,QAAmC;GAC/C,MAAM,QAAQ,MAAM,MAAM;GAC1B,MAAM,MAAgB,CAAC;GACvB,IAAI;GAEJ,GAAG;IACD,MAAM,OAAO,MAAM,UAAU,KAAK;KAAE,QAAQ;KAAO,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;IAAG,CAAC;IAClF,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI,KAAK,QAAQ,EAAE,IAAI,CAAC;IACnD,SAAS,KAAK,gBAAgB,KAAA,IAAY,KAAK;GACjD,SAAS;GACT,OAAO;EACT;CACF;AACF"}
@@ -0,0 +1,78 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let drizzle_orm = require("drizzle-orm");
3
+ //#region src/storage/drizzle.ts
4
+ /**
5
+ * Drizzle storage adapter — a {@link WebhooksStorage} over a **consumer-owned**
6
+ * Drizzle table and database. Unlike {@link ./postgres.createPostgresStorage} it
7
+ * issues **no DDL** (the table lives in your Drizzle schema + migrations) and
8
+ * **owns no connection** (it reuses the `db` you pass, and never closes it).
9
+ *
10
+ * Dialect-agnostic: works with Postgres, MySQL, and SQLite Drizzle databases.
11
+ * Build the backing table with the matching factory —
12
+ * {@link ../drizzle/pg.pgWebhooksTable} / {@link ../drizzle/mysql.mysqlWebhooksTable} /
13
+ * {@link ../drizzle/sqlite.sqliteWebhooksTable} — whose fixed `key`/`value`
14
+ * columns this adapter reads and writes.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { drizzle } from "drizzle-orm/node-postgres";
19
+ * import { createDrizzleStorage } from "@xtandard/webhooks/storage/drizzle";
20
+ * import { pgWebhooksTable } from "@xtandard/webhooks/drizzle/pg";
21
+ *
22
+ * export const webhooksKv = pgWebhooksTable(); // add to your schema + migrate
23
+ * const db = drizzle(pool); // your existing pool
24
+ * const storage = createDrizzleStorage({ db, table: webhooksKv });
25
+ * ```
26
+ *
27
+ * @module
28
+ */
29
+ /** Escape LIKE wildcards so `getKeys` matches the prefix verbatim (paired with `ESCAPE '\'`). */
30
+ const escapeLike = (literal) => literal.replace(/[\\%_]/g, (c) => `\\${c}`);
31
+ /** Parse a value defensively — Drizzle returns json parsed, but a string is parsed too. */
32
+ const parseValue = (value) => {
33
+ if (typeof value === "string") try {
34
+ return JSON.parse(value);
35
+ } catch {
36
+ return value;
37
+ }
38
+ return value;
39
+ };
40
+ /**
41
+ * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection
42
+ * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL
43
+ * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.
44
+ */
45
+ function createDrizzleStorage(options) {
46
+ const db = options.db;
47
+ const { table } = options;
48
+ return {
49
+ async getItem(key) {
50
+ const row = (await db.select({ value: table.value }).from(table).where((0, drizzle_orm.eq)(table.key, key)))[0];
51
+ if (row === void 0 || row.value === null || row.value === void 0) return null;
52
+ return parseValue(row.value);
53
+ },
54
+ async setItem(key, value) {
55
+ const insert = db.insert(table).values({
56
+ key,
57
+ value
58
+ });
59
+ if (typeof insert.onConflictDoUpdate === "function") await insert.onConflictDoUpdate({
60
+ target: table.key,
61
+ set: { value }
62
+ });
63
+ else if (typeof insert.onDuplicateKeyUpdate === "function") await insert.onDuplicateKeyUpdate({ set: { value } });
64
+ else throw new Error("createDrizzleStorage: the Drizzle database exposes no known upsert method (onConflictDoUpdate / onDuplicateKeyUpdate).");
65
+ },
66
+ async removeItem(key) {
67
+ await db.delete(table).where((0, drizzle_orm.eq)(table.key, key));
68
+ },
69
+ async getKeys(prefix) {
70
+ const pattern = `${escapeLike(prefix)}%`;
71
+ return (await db.select({ key: table.key }).from(table).where(drizzle_orm.sql`${table.key} like ${pattern} escape '\\'`)).map((row) => String(row.key));
72
+ }
73
+ };
74
+ }
75
+ //#endregion
76
+ exports.createDrizzleStorage = createDrizzleStorage;
77
+
78
+ //# sourceMappingURL=entry-storage-drizzle.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-storage-drizzle.cjs","names":[],"sources":["../src/storage/drizzle.ts"],"sourcesContent":["/**\n * Drizzle storage adapter — a {@link WebhooksStorage} over a **consumer-owned**\n * Drizzle table and database. Unlike {@link ./postgres.createPostgresStorage} it\n * issues **no DDL** (the table lives in your Drizzle schema + migrations) and\n * **owns no connection** (it reuses the `db` you pass, and never closes it).\n *\n * Dialect-agnostic: works with Postgres, MySQL, and SQLite Drizzle databases.\n * Build the backing table with the matching factory —\n * {@link ../drizzle/pg.pgWebhooksTable} / {@link ../drizzle/mysql.mysqlWebhooksTable} /\n * {@link ../drizzle/sqlite.sqliteWebhooksTable} — whose fixed `key`/`value`\n * columns this adapter reads and writes.\n *\n * @example\n * ```ts\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { createDrizzleStorage } from \"@xtandard/webhooks/storage/drizzle\";\n * import { pgWebhooksTable } from \"@xtandard/webhooks/drizzle/pg\";\n *\n * export const webhooksKv = pgWebhooksTable(); // add to your schema + migrate\n * const db = drizzle(pool); // your existing pool\n * const storage = createDrizzleStorage({ db, table: webhooksKv });\n * ```\n *\n * @module\n */\n\nimport { eq, sql, type Column, type SQL, type Table } from \"drizzle-orm\";\nimport type { WebhooksStorage } from \"./contract.ts\";\nimport type { DrizzleKvTable } from \"../drizzle/table.ts\";\n\nexport type { DrizzleKvTable } from \"../drizzle/table.ts\";\n\n/**\n * Minimal structural view of a Drizzle database — the query-builder entry points\n * the KV adapter uses. This is the internal contract the adapter casts `db` to;\n * the public option is typed `unknown` because a dialect-agnostic structural type\n * cannot match dialect-specific dbs (their `.from`/`.insert` want `PgTable` etc.,\n * not the base `Table`). The upsert method differs by dialect and is\n * feature-detected at runtime.\n */\ninterface DrizzleLikeDatabase {\n select(fields: Record<string, Column>): {\n from(table: Table): { where(where: SQL): PromiseLike<unknown[]> };\n };\n insert(table: Table): {\n values(row: { key: string; value: unknown }): {\n /** Postgres + SQLite upsert. */\n onConflictDoUpdate?(config: {\n target: Column;\n set: { value: unknown };\n }): PromiseLike<unknown>;\n /** MySQL upsert. */\n onDuplicateKeyUpdate?(config: { set: { value: unknown } }): PromiseLike<unknown>;\n };\n };\n delete(table: Table): { where(where: SQL): PromiseLike<unknown> };\n}\n\n/** Options for {@link createDrizzleStorage}. */\nexport interface DrizzleStorageOptions {\n /**\n * Your Drizzle database (node-postgres / mysql2 / better-sqlite3 / pglite / …).\n * Typed `unknown` intentionally — a single dialect-agnostic type can't match\n * every dialect's db; the adapter only calls `select`/`insert`/`delete`.\n */\n db: unknown;\n /** The KV table built with a `*WebhooksTable` factory (or matching that shape). */\n table: DrizzleKvTable;\n}\n\n/**\n * A {@link WebhooksStorage} over a Drizzle table. For push change-notifications,\n * compose it with {@link ./watch.withWatch} + a change source (e.g.\n * {@link ./watch.pgListenNotify}) — `watch` is orthogonal to the adapter.\n */\nexport type DrizzleWebhooksStorage = WebhooksStorage;\n\n/** Escape LIKE wildcards so `getKeys` matches the prefix verbatim (paired with `ESCAPE '\\'`). */\nconst escapeLike = (literal: string): string => literal.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n\n/** Parse a value defensively — Drizzle returns json parsed, but a string is parsed too. */\nconst parseValue = <T>(value: unknown): T => {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value) as T;\n } catch {\n return value as T;\n }\n }\n return value as T;\n};\n\n/**\n * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection\n * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL\n * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.\n */\nexport function createDrizzleStorage(options: DrizzleStorageOptions): DrizzleWebhooksStorage {\n const db = options.db as DrizzleLikeDatabase;\n const { table } = options;\n\n return {\n async getItem<T>(key: string): Promise<T | null> {\n const rows = (await db\n .select({ value: table.value })\n .from(table)\n .where(eq(table.key, key))) as Array<{ value: unknown }>;\n const row = rows[0];\n if (row === undefined || row.value === null || row.value === undefined) return null;\n return parseValue<T>(row.value);\n },\n\n async setItem<T>(key: string, value: T): Promise<void> {\n const insert = db.insert(table).values({ key, value });\n if (typeof insert.onConflictDoUpdate === \"function\") {\n await insert.onConflictDoUpdate({ target: table.key, set: { value } });\n } else if (typeof insert.onDuplicateKeyUpdate === \"function\") {\n await insert.onDuplicateKeyUpdate({ set: { value } });\n } else {\n throw new Error(\n \"createDrizzleStorage: the Drizzle database exposes no known upsert method \" +\n \"(onConflictDoUpdate / onDuplicateKeyUpdate).\",\n );\n }\n },\n\n async removeItem(key: string): Promise<void> {\n await db.delete(table).where(eq(table.key, key));\n },\n\n async getKeys(prefix: string): Promise<string[]> {\n const pattern = `${escapeLike(prefix)}%`;\n const rows = (await db\n .select({ key: table.key })\n .from(table)\n .where(sql`${table.key} like ${pattern} escape '\\\\'`)) as Array<{ key: unknown }>;\n return rows.map((row) => String(row.key));\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,MAAM,cAAc,YAA4B,QAAQ,QAAQ,YAAY,MAAM,KAAK,GAAG;;AAG1F,MAAM,cAAiB,UAAsB;CAC3C,IAAI,OAAO,UAAU,UACnB,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;CAEF,OAAO;AACT;;;;;;AAOA,SAAgB,qBAAqB,SAAwD;CAC3F,MAAM,KAAK,QAAQ;CACnB,MAAM,EAAE,UAAU;CAElB,OAAO;EACL,MAAM,QAAW,KAAgC;GAK/C,MAAM,OAAM,MAJQ,GACjB,OAAO,EAAE,OAAO,MAAM,MAAM,CAAC,EAC7B,KAAK,KAAK,EACV,OAAA,GAAA,YAAA,IAAS,MAAM,KAAK,GAAG,CAAC,GACV;GACjB,IAAI,QAAQ,KAAA,KAAa,IAAI,UAAU,QAAQ,IAAI,UAAU,KAAA,GAAW,OAAO;GAC/E,OAAO,WAAc,IAAI,KAAK;EAChC;EAEA,MAAM,QAAW,KAAa,OAAyB;GACrD,MAAM,SAAS,GAAG,OAAO,KAAK,EAAE,OAAO;IAAE;IAAK;GAAM,CAAC;GACrD,IAAI,OAAO,OAAO,uBAAuB,YACvC,MAAM,OAAO,mBAAmB;IAAE,QAAQ,MAAM;IAAK,KAAK,EAAE,MAAM;GAAE,CAAC;QAChE,IAAI,OAAO,OAAO,yBAAyB,YAChD,MAAM,OAAO,qBAAqB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAEpD,MAAM,IAAI,MACR,wHAEF;EAEJ;EAEA,MAAM,WAAW,KAA4B;GAC3C,MAAM,GAAG,OAAO,KAAK,EAAE,OAAA,GAAA,YAAA,IAAS,MAAM,KAAK,GAAG,CAAC;EACjD;EAEA,MAAM,QAAQ,QAAmC;GAC/C,MAAM,UAAU,GAAG,WAAW,MAAM,EAAE;GAKtC,QAAO,MAJa,GACjB,OAAO,EAAE,KAAK,MAAM,IAAI,CAAC,EACzB,KAAK,KAAK,EACV,MAAM,YAAA,GAAG,GAAG,MAAM,IAAI,QAAQ,QAAQ,aAAa,GAC1C,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC;EAC1C;CACF;AACF"}
@@ -0,0 +1,30 @@
1
+ import { o as WebhooksStorage } from "./contract-8h-Azxa5.cjs";
2
+ import { t as DrizzleKvTable } from "./table-Ce3Tzwqs.cjs";
3
+
4
+ //#region src/storage/drizzle.d.ts
5
+ /** Options for {@link createDrizzleStorage}. */
6
+ interface DrizzleStorageOptions {
7
+ /**
8
+ * Your Drizzle database (node-postgres / mysql2 / better-sqlite3 / pglite / …).
9
+ * Typed `unknown` intentionally — a single dialect-agnostic type can't match
10
+ * every dialect's db; the adapter only calls `select`/`insert`/`delete`.
11
+ */
12
+ db: unknown;
13
+ /** The KV table built with a `*WebhooksTable` factory (or matching that shape). */
14
+ table: DrizzleKvTable;
15
+ }
16
+ /**
17
+ * A {@link WebhooksStorage} over a Drizzle table. For push change-notifications,
18
+ * compose it with {@link ./watch.withWatch} + a change source (e.g.
19
+ * {@link ./watch.pgListenNotify}) — `watch` is orthogonal to the adapter.
20
+ */
21
+ type DrizzleWebhooksStorage = WebhooksStorage;
22
+ /**
23
+ * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection
24
+ * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL
25
+ * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.
26
+ */
27
+ declare function createDrizzleStorage(options: DrizzleStorageOptions): DrizzleWebhooksStorage;
28
+ //#endregion
29
+ export { type DrizzleKvTable, DrizzleStorageOptions, DrizzleWebhooksStorage, createDrizzleStorage };
30
+ //# sourceMappingURL=entry-storage-drizzle.d.cts.map
@@ -0,0 +1,30 @@
1
+ import { o as WebhooksStorage } from "./contract-DhQ4JjGG.mjs";
2
+ import { t as DrizzleKvTable } from "./table-Ce3Tzwqs.mjs";
3
+
4
+ //#region src/storage/drizzle.d.ts
5
+ /** Options for {@link createDrizzleStorage}. */
6
+ interface DrizzleStorageOptions {
7
+ /**
8
+ * Your Drizzle database (node-postgres / mysql2 / better-sqlite3 / pglite / …).
9
+ * Typed `unknown` intentionally — a single dialect-agnostic type can't match
10
+ * every dialect's db; the adapter only calls `select`/`insert`/`delete`.
11
+ */
12
+ db: unknown;
13
+ /** The KV table built with a `*WebhooksTable` factory (or matching that shape). */
14
+ table: DrizzleKvTable;
15
+ }
16
+ /**
17
+ * A {@link WebhooksStorage} over a Drizzle table. For push change-notifications,
18
+ * compose it with {@link ./watch.withWatch} + a change source (e.g.
19
+ * {@link ./watch.pgListenNotify}) — `watch` is orthogonal to the adapter.
20
+ */
21
+ type DrizzleWebhooksStorage = WebhooksStorage;
22
+ /**
23
+ * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection
24
+ * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL
25
+ * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.
26
+ */
27
+ declare function createDrizzleStorage(options: DrizzleStorageOptions): DrizzleWebhooksStorage;
28
+ //#endregion
29
+ export { type DrizzleKvTable, DrizzleStorageOptions, DrizzleWebhooksStorage, createDrizzleStorage };
30
+ //# sourceMappingURL=entry-storage-drizzle.d.mts.map
@@ -0,0 +1,77 @@
1
+ import { eq, sql } from "drizzle-orm";
2
+ //#region src/storage/drizzle.ts
3
+ /**
4
+ * Drizzle storage adapter — a {@link WebhooksStorage} over a **consumer-owned**
5
+ * Drizzle table and database. Unlike {@link ./postgres.createPostgresStorage} it
6
+ * issues **no DDL** (the table lives in your Drizzle schema + migrations) and
7
+ * **owns no connection** (it reuses the `db` you pass, and never closes it).
8
+ *
9
+ * Dialect-agnostic: works with Postgres, MySQL, and SQLite Drizzle databases.
10
+ * Build the backing table with the matching factory —
11
+ * {@link ../drizzle/pg.pgWebhooksTable} / {@link ../drizzle/mysql.mysqlWebhooksTable} /
12
+ * {@link ../drizzle/sqlite.sqliteWebhooksTable} — whose fixed `key`/`value`
13
+ * columns this adapter reads and writes.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { drizzle } from "drizzle-orm/node-postgres";
18
+ * import { createDrizzleStorage } from "@xtandard/webhooks/storage/drizzle";
19
+ * import { pgWebhooksTable } from "@xtandard/webhooks/drizzle/pg";
20
+ *
21
+ * export const webhooksKv = pgWebhooksTable(); // add to your schema + migrate
22
+ * const db = drizzle(pool); // your existing pool
23
+ * const storage = createDrizzleStorage({ db, table: webhooksKv });
24
+ * ```
25
+ *
26
+ * @module
27
+ */
28
+ /** Escape LIKE wildcards so `getKeys` matches the prefix verbatim (paired with `ESCAPE '\'`). */
29
+ const escapeLike = (literal) => literal.replace(/[\\%_]/g, (c) => `\\${c}`);
30
+ /** Parse a value defensively — Drizzle returns json parsed, but a string is parsed too. */
31
+ const parseValue = (value) => {
32
+ if (typeof value === "string") try {
33
+ return JSON.parse(value);
34
+ } catch {
35
+ return value;
36
+ }
37
+ return value;
38
+ };
39
+ /**
40
+ * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection
41
+ * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL
42
+ * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.
43
+ */
44
+ function createDrizzleStorage(options) {
45
+ const db = options.db;
46
+ const { table } = options;
47
+ return {
48
+ async getItem(key) {
49
+ const row = (await db.select({ value: table.value }).from(table).where(eq(table.key, key)))[0];
50
+ if (row === void 0 || row.value === null || row.value === void 0) return null;
51
+ return parseValue(row.value);
52
+ },
53
+ async setItem(key, value) {
54
+ const insert = db.insert(table).values({
55
+ key,
56
+ value
57
+ });
58
+ if (typeof insert.onConflictDoUpdate === "function") await insert.onConflictDoUpdate({
59
+ target: table.key,
60
+ set: { value }
61
+ });
62
+ else if (typeof insert.onDuplicateKeyUpdate === "function") await insert.onDuplicateKeyUpdate({ set: { value } });
63
+ else throw new Error("createDrizzleStorage: the Drizzle database exposes no known upsert method (onConflictDoUpdate / onDuplicateKeyUpdate).");
64
+ },
65
+ async removeItem(key) {
66
+ await db.delete(table).where(eq(table.key, key));
67
+ },
68
+ async getKeys(prefix) {
69
+ const pattern = `${escapeLike(prefix)}%`;
70
+ return (await db.select({ key: table.key }).from(table).where(sql`${table.key} like ${pattern} escape '\\'`)).map((row) => String(row.key));
71
+ }
72
+ };
73
+ }
74
+ //#endregion
75
+ export { createDrizzleStorage };
76
+
77
+ //# sourceMappingURL=entry-storage-drizzle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-storage-drizzle.mjs","names":[],"sources":["../src/storage/drizzle.ts"],"sourcesContent":["/**\n * Drizzle storage adapter — a {@link WebhooksStorage} over a **consumer-owned**\n * Drizzle table and database. Unlike {@link ./postgres.createPostgresStorage} it\n * issues **no DDL** (the table lives in your Drizzle schema + migrations) and\n * **owns no connection** (it reuses the `db` you pass, and never closes it).\n *\n * Dialect-agnostic: works with Postgres, MySQL, and SQLite Drizzle databases.\n * Build the backing table with the matching factory —\n * {@link ../drizzle/pg.pgWebhooksTable} / {@link ../drizzle/mysql.mysqlWebhooksTable} /\n * {@link ../drizzle/sqlite.sqliteWebhooksTable} — whose fixed `key`/`value`\n * columns this adapter reads and writes.\n *\n * @example\n * ```ts\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { createDrizzleStorage } from \"@xtandard/webhooks/storage/drizzle\";\n * import { pgWebhooksTable } from \"@xtandard/webhooks/drizzle/pg\";\n *\n * export const webhooksKv = pgWebhooksTable(); // add to your schema + migrate\n * const db = drizzle(pool); // your existing pool\n * const storage = createDrizzleStorage({ db, table: webhooksKv });\n * ```\n *\n * @module\n */\n\nimport { eq, sql, type Column, type SQL, type Table } from \"drizzle-orm\";\nimport type { WebhooksStorage } from \"./contract.ts\";\nimport type { DrizzleKvTable } from \"../drizzle/table.ts\";\n\nexport type { DrizzleKvTable } from \"../drizzle/table.ts\";\n\n/**\n * Minimal structural view of a Drizzle database — the query-builder entry points\n * the KV adapter uses. This is the internal contract the adapter casts `db` to;\n * the public option is typed `unknown` because a dialect-agnostic structural type\n * cannot match dialect-specific dbs (their `.from`/`.insert` want `PgTable` etc.,\n * not the base `Table`). The upsert method differs by dialect and is\n * feature-detected at runtime.\n */\ninterface DrizzleLikeDatabase {\n select(fields: Record<string, Column>): {\n from(table: Table): { where(where: SQL): PromiseLike<unknown[]> };\n };\n insert(table: Table): {\n values(row: { key: string; value: unknown }): {\n /** Postgres + SQLite upsert. */\n onConflictDoUpdate?(config: {\n target: Column;\n set: { value: unknown };\n }): PromiseLike<unknown>;\n /** MySQL upsert. */\n onDuplicateKeyUpdate?(config: { set: { value: unknown } }): PromiseLike<unknown>;\n };\n };\n delete(table: Table): { where(where: SQL): PromiseLike<unknown> };\n}\n\n/** Options for {@link createDrizzleStorage}. */\nexport interface DrizzleStorageOptions {\n /**\n * Your Drizzle database (node-postgres / mysql2 / better-sqlite3 / pglite / …).\n * Typed `unknown` intentionally — a single dialect-agnostic type can't match\n * every dialect's db; the adapter only calls `select`/`insert`/`delete`.\n */\n db: unknown;\n /** The KV table built with a `*WebhooksTable` factory (or matching that shape). */\n table: DrizzleKvTable;\n}\n\n/**\n * A {@link WebhooksStorage} over a Drizzle table. For push change-notifications,\n * compose it with {@link ./watch.withWatch} + a change source (e.g.\n * {@link ./watch.pgListenNotify}) — `watch` is orthogonal to the adapter.\n */\nexport type DrizzleWebhooksStorage = WebhooksStorage;\n\n/** Escape LIKE wildcards so `getKeys` matches the prefix verbatim (paired with `ESCAPE '\\'`). */\nconst escapeLike = (literal: string): string => literal.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n\n/** Parse a value defensively — Drizzle returns json parsed, but a string is parsed too. */\nconst parseValue = <T>(value: unknown): T => {\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value) as T;\n } catch {\n return value as T;\n }\n }\n return value as T;\n};\n\n/**\n * Create a Drizzle-backed {@link DrizzleWebhooksStorage}. No DDL, no connection\n * ownership. The upsert dialect (Postgres/SQLite `onConflictDoUpdate` vs MySQL\n * `onDuplicateKeyUpdate`) is detected at runtime from the insert builder.\n */\nexport function createDrizzleStorage(options: DrizzleStorageOptions): DrizzleWebhooksStorage {\n const db = options.db as DrizzleLikeDatabase;\n const { table } = options;\n\n return {\n async getItem<T>(key: string): Promise<T | null> {\n const rows = (await db\n .select({ value: table.value })\n .from(table)\n .where(eq(table.key, key))) as Array<{ value: unknown }>;\n const row = rows[0];\n if (row === undefined || row.value === null || row.value === undefined) return null;\n return parseValue<T>(row.value);\n },\n\n async setItem<T>(key: string, value: T): Promise<void> {\n const insert = db.insert(table).values({ key, value });\n if (typeof insert.onConflictDoUpdate === \"function\") {\n await insert.onConflictDoUpdate({ target: table.key, set: { value } });\n } else if (typeof insert.onDuplicateKeyUpdate === \"function\") {\n await insert.onDuplicateKeyUpdate({ set: { value } });\n } else {\n throw new Error(\n \"createDrizzleStorage: the Drizzle database exposes no known upsert method \" +\n \"(onConflictDoUpdate / onDuplicateKeyUpdate).\",\n );\n }\n },\n\n async removeItem(key: string): Promise<void> {\n await db.delete(table).where(eq(table.key, key));\n },\n\n async getKeys(prefix: string): Promise<string[]> {\n const pattern = `${escapeLike(prefix)}%`;\n const rows = (await db\n .select({ key: table.key })\n .from(table)\n .where(sql`${table.key} like ${pattern} escape '\\\\'`)) as Array<{ key: unknown }>;\n return rows.map((row) => String(row.key));\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,MAAM,cAAc,YAA4B,QAAQ,QAAQ,YAAY,MAAM,KAAK,GAAG;;AAG1F,MAAM,cAAiB,UAAsB;CAC3C,IAAI,OAAO,UAAU,UACnB,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;CAEF,OAAO;AACT;;;;;;AAOA,SAAgB,qBAAqB,SAAwD;CAC3F,MAAM,KAAK,QAAQ;CACnB,MAAM,EAAE,UAAU;CAElB,OAAO;EACL,MAAM,QAAW,KAAgC;GAK/C,MAAM,OAAM,MAJQ,GACjB,OAAO,EAAE,OAAO,MAAM,MAAM,CAAC,EAC7B,KAAK,KAAK,EACV,MAAM,GAAG,MAAM,KAAK,GAAG,CAAC,GACV;GACjB,IAAI,QAAQ,KAAA,KAAa,IAAI,UAAU,QAAQ,IAAI,UAAU,KAAA,GAAW,OAAO;GAC/E,OAAO,WAAc,IAAI,KAAK;EAChC;EAEA,MAAM,QAAW,KAAa,OAAyB;GACrD,MAAM,SAAS,GAAG,OAAO,KAAK,EAAE,OAAO;IAAE;IAAK;GAAM,CAAC;GACrD,IAAI,OAAO,OAAO,uBAAuB,YACvC,MAAM,OAAO,mBAAmB;IAAE,QAAQ,MAAM;IAAK,KAAK,EAAE,MAAM;GAAE,CAAC;QAChE,IAAI,OAAO,OAAO,yBAAyB,YAChD,MAAM,OAAO,qBAAqB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAEpD,MAAM,IAAI,MACR,wHAEF;EAEJ;EAEA,MAAM,WAAW,KAA4B;GAC3C,MAAM,GAAG,OAAO,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,GAAG,CAAC;EACjD;EAEA,MAAM,QAAQ,QAAmC;GAC/C,MAAM,UAAU,GAAG,WAAW,MAAM,EAAE;GAKtC,QAAO,MAJa,GACjB,OAAO,EAAE,KAAK,MAAM,IAAI,CAAC,EACzB,KAAK,KAAK,EACV,MAAM,GAAG,GAAG,MAAM,IAAI,QAAQ,QAAQ,aAAa,GAC1C,KAAK,QAAQ,OAAO,IAAI,GAAG,CAAC;EAC1C;CACF;AACF"}
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_file = require("./file-COBYZA4Q.cjs");
3
+ exports.clearFileStorage = require_file.clearFileStorage;
4
+ exports.createFileStorage = require_file.createFileStorage;
@@ -0,0 +1,30 @@
1
+ import { a as WatchableWebhooksStorage } from "./contract-8h-Azxa5.cjs";
2
+
3
+ //#region src/storage/file.d.ts
4
+ /** Options for {@link createFileStorage}. */
5
+ interface FileStorageOptions {
6
+ /** Base directory under which key files are written. Created on demand. */
7
+ dir: string;
8
+ }
9
+ /**
10
+ * Create a file-backed {@link WatchableWebhooksStorage}. Values are serialized
11
+ * as pretty-printed JSON. `watch` is implemented via `fs.watch` on the base
12
+ * directory (recursive); it is best-effort and may coalesce or miss events on
13
+ * platforms without recursive-watch support.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { createFileStorage } from "@xtandard/webhooks/storage/file";
18
+ *
19
+ * const storage = createFileStorage({ dir: "./data/webhooks" });
20
+ * ```
21
+ */
22
+ declare function createFileStorage(options: FileStorageOptions): WatchableWebhooksStorage;
23
+ /**
24
+ * Delete every file written by a {@link createFileStorage} instance by removing
25
+ * its base directory. Exposed primarily for tests and cleanup tooling.
26
+ */
27
+ declare function clearFileStorage(options: FileStorageOptions): Promise<void>;
28
+ //#endregion
29
+ export { FileStorageOptions, clearFileStorage, createFileStorage };
30
+ //# sourceMappingURL=entry-storage-file.d.cts.map
@@ -0,0 +1,30 @@
1
+ import { a as WatchableWebhooksStorage } from "./contract-DhQ4JjGG.mjs";
2
+
3
+ //#region src/storage/file.d.ts
4
+ /** Options for {@link createFileStorage}. */
5
+ interface FileStorageOptions {
6
+ /** Base directory under which key files are written. Created on demand. */
7
+ dir: string;
8
+ }
9
+ /**
10
+ * Create a file-backed {@link WatchableWebhooksStorage}. Values are serialized
11
+ * as pretty-printed JSON. `watch` is implemented via `fs.watch` on the base
12
+ * directory (recursive); it is best-effort and may coalesce or miss events on
13
+ * platforms without recursive-watch support.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { createFileStorage } from "@xtandard/webhooks/storage/file";
18
+ *
19
+ * const storage = createFileStorage({ dir: "./data/webhooks" });
20
+ * ```
21
+ */
22
+ declare function createFileStorage(options: FileStorageOptions): WatchableWebhooksStorage;
23
+ /**
24
+ * Delete every file written by a {@link createFileStorage} instance by removing
25
+ * its base directory. Exposed primarily for tests and cleanup tooling.
26
+ */
27
+ declare function clearFileStorage(options: FileStorageOptions): Promise<void>;
28
+ //#endregion
29
+ export { FileStorageOptions, clearFileStorage, createFileStorage };
30
+ //# sourceMappingURL=entry-storage-file.d.mts.map
@@ -0,0 +1,2 @@
1
+ import { n as createFileStorage, t as clearFileStorage } from "./file-fi02eFHk.mjs";
2
+ export { clearFileStorage, createFileStorage };
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_libsql = require("./libsql-pPJEo1e4.cjs");
3
+ exports.createLibsqlStorage = require_libsql.createLibsqlStorage;
@@ -0,0 +1,48 @@
1
+ import { o as WebhooksStorage } from "./contract-8h-Azxa5.cjs";
2
+
3
+ //#region src/storage/libsql.d.ts
4
+ /** Options for {@link createLibsqlStorage}. */
5
+ interface LibsqlStorageOptions {
6
+ /** libSQL connection URL (`libsql://…`, `https://…`, `file:…`, `:memory:`). Used when no `client`. */
7
+ url?: string;
8
+ /** Turso auth token for remote databases. */
9
+ authToken?: string;
10
+ /** A pre-constructed `@libsql/client` client to use instead of connecting. */
11
+ client?: LibsqlClientLike;
12
+ /** Table name (default `"xtandard_webhooks"`). Validated as a safe identifier. */
13
+ table?: string;
14
+ }
15
+ /** A {@link WebhooksStorage} backed by libSQL/Turso, plus `close()`. */
16
+ interface LibsqlWebhooksStorage extends WebhooksStorage {
17
+ /** Close the client if this adapter created it; no-op for a borrowed instance. */
18
+ close(): void;
19
+ }
20
+ /** Minimal structural view of the `@libsql/client` surface this adapter uses. */
21
+ interface LibsqlClientLike {
22
+ execute(stmt: string | {
23
+ sql: string;
24
+ args: unknown[];
25
+ }): Promise<{
26
+ rows: Array<Record<string, unknown>>;
27
+ }>;
28
+ close(): void;
29
+ }
30
+ /**
31
+ * Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created
32
+ * on first use; connection (when constructed from `url`) is lazy and shared.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
37
+ *
38
+ * const storage = createLibsqlStorage({
39
+ * url: process.env.TURSO_DATABASE_URL!,
40
+ * authToken: process.env.TURSO_AUTH_TOKEN,
41
+ * });
42
+ * // process.on("SIGTERM", () => storage.close());
43
+ * ```
44
+ */
45
+ declare function createLibsqlStorage(options: LibsqlStorageOptions): LibsqlWebhooksStorage;
46
+ //#endregion
47
+ export { LibsqlClientLike, LibsqlStorageOptions, LibsqlWebhooksStorage, createLibsqlStorage };
48
+ //# sourceMappingURL=entry-storage-libsql.d.cts.map
@@ -0,0 +1,48 @@
1
+ import { o as WebhooksStorage } from "./contract-DhQ4JjGG.mjs";
2
+
3
+ //#region src/storage/libsql.d.ts
4
+ /** Options for {@link createLibsqlStorage}. */
5
+ interface LibsqlStorageOptions {
6
+ /** libSQL connection URL (`libsql://…`, `https://…`, `file:…`, `:memory:`). Used when no `client`. */
7
+ url?: string;
8
+ /** Turso auth token for remote databases. */
9
+ authToken?: string;
10
+ /** A pre-constructed `@libsql/client` client to use instead of connecting. */
11
+ client?: LibsqlClientLike;
12
+ /** Table name (default `"xtandard_webhooks"`). Validated as a safe identifier. */
13
+ table?: string;
14
+ }
15
+ /** A {@link WebhooksStorage} backed by libSQL/Turso, plus `close()`. */
16
+ interface LibsqlWebhooksStorage extends WebhooksStorage {
17
+ /** Close the client if this adapter created it; no-op for a borrowed instance. */
18
+ close(): void;
19
+ }
20
+ /** Minimal structural view of the `@libsql/client` surface this adapter uses. */
21
+ interface LibsqlClientLike {
22
+ execute(stmt: string | {
23
+ sql: string;
24
+ args: unknown[];
25
+ }): Promise<{
26
+ rows: Array<Record<string, unknown>>;
27
+ }>;
28
+ close(): void;
29
+ }
30
+ /**
31
+ * Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created
32
+ * on first use; connection (when constructed from `url`) is lazy and shared.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
37
+ *
38
+ * const storage = createLibsqlStorage({
39
+ * url: process.env.TURSO_DATABASE_URL!,
40
+ * authToken: process.env.TURSO_AUTH_TOKEN,
41
+ * });
42
+ * // process.on("SIGTERM", () => storage.close());
43
+ * ```
44
+ */
45
+ declare function createLibsqlStorage(options: LibsqlStorageOptions): LibsqlWebhooksStorage;
46
+ //#endregion
47
+ export { LibsqlClientLike, LibsqlStorageOptions, LibsqlWebhooksStorage, createLibsqlStorage };
48
+ //# sourceMappingURL=entry-storage-libsql.d.mts.map
@@ -0,0 +1,2 @@
1
+ import { t as createLibsqlStorage } from "./libsql-bpVi0bXN.mjs";
2
+ export { createLibsqlStorage };
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_memory = require("./memory-8Ef-PL5a.cjs");
3
+ exports.createMemoryStorage = require_memory.createMemoryStorage;
@@ -0,0 +1,2 @@
1
+ import { n as MemoryWebhooksStorage, r as createMemoryStorage, t as MemoryStorageOptions } from "./memory-FnMJWCmB.cjs";
2
+ export { MemoryStorageOptions, MemoryWebhooksStorage, createMemoryStorage };
@@ -0,0 +1,2 @@
1
+ import { n as MemoryWebhooksStorage, r as createMemoryStorage, t as MemoryStorageOptions } from "./memory-qIvANEs_.mjs";
2
+ export { MemoryStorageOptions, MemoryWebhooksStorage, createMemoryStorage };
@@ -0,0 +1,2 @@
1
+ import { t as createMemoryStorage } from "./memory-BMsSSwqn.mjs";
2
+ export { createMemoryStorage };
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_mongodb = require("./mongodb-Cy8yo0uk.cjs");
3
+ exports.createMongoStorage = require_mongodb.createMongoStorage;