@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.
- package/LICENSE +21 -0
- package/README.md +315 -0
- package/bin/xtandard-webhooks.mjs +3 -0
- package/dist/basic-BIW3Rvuz.cjs +199 -0
- package/dist/basic-BIW3Rvuz.cjs.map +1 -0
- package/dist/basic-DKk0Xfuu.mjs +176 -0
- package/dist/basic-DKk0Xfuu.mjs.map +1 -0
- package/dist/chunk-D7D4PA-g.mjs +13 -0
- package/dist/cli.cjs +655 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +42 -0
- package/dist/cli.d.mts +42 -0
- package/dist/cli.mjs +653 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/contract-8h-Azxa5.d.cts +71 -0
- package/dist/contract-9XpcwcCn.mjs +22 -0
- package/dist/contract-9XpcwcCn.mjs.map +1 -0
- package/dist/contract-B2d5dNU3.cjs +33 -0
- package/dist/contract-B2d5dNU3.cjs.map +1 -0
- package/dist/contract-BEhDcd_5.mjs +28 -0
- package/dist/contract-BEhDcd_5.mjs.map +1 -0
- package/dist/contract-Bf1qguwt.cjs +57 -0
- package/dist/contract-Bf1qguwt.cjs.map +1 -0
- package/dist/contract-Bnb3fgRJ.d.cts +177 -0
- package/dist/contract-C2r2Xzwp.d.mts +46 -0
- package/dist/contract-CiPskNvS.d.cts +46 -0
- package/dist/contract-DhQ4JjGG.d.mts +71 -0
- package/dist/contract-T1kcZNdG.d.mts +177 -0
- package/dist/contract-lETlIuXo.d.cts +30 -0
- package/dist/contract-lETlIuXo.d.mts +30 -0
- package/dist/core-CMpnmI5Q.mjs +1605 -0
- package/dist/core-CMpnmI5Q.mjs.map +1 -0
- package/dist/core-DT4ppWh8.d.mts +502 -0
- package/dist/core-KJawHjFF.d.cts +502 -0
- package/dist/core-ZGhH6Vs2.cjs +1790 -0
- package/dist/core-ZGhH6Vs2.cjs.map +1 -0
- package/dist/core.cjs +8 -0
- package/dist/core.d.cts +2 -0
- package/dist/core.d.mts +2 -0
- package/dist/core.mjs +2 -0
- package/dist/create-fetch-handler-BIdk9P30.mjs +1724 -0
- package/dist/create-fetch-handler-BIdk9P30.mjs.map +1 -0
- package/dist/create-fetch-handler-CmooujQo.cjs +1771 -0
- package/dist/create-fetch-handler-CmooujQo.cjs.map +1 -0
- package/dist/create-fetch-handler-Dlkhustu.d.cts +162 -0
- package/dist/create-fetch-handler-jy3hy5nZ.d.mts +162 -0
- package/dist/dispatcher-B0xTEHt1.cjs +212 -0
- package/dist/dispatcher-B0xTEHt1.cjs.map +1 -0
- package/dist/dispatcher-Coubwrka.mjs +196 -0
- package/dist/dispatcher-Coubwrka.mjs.map +1 -0
- package/dist/entry-auth-basic.cjs +5 -0
- package/dist/entry-auth-basic.d.cts +83 -0
- package/dist/entry-auth-basic.d.mts +83 -0
- package/dist/entry-auth-basic.mjs +2 -0
- package/dist/entry-auth-delegated.cjs +28 -0
- package/dist/entry-auth-delegated.cjs.map +1 -0
- package/dist/entry-auth-delegated.d.cts +36 -0
- package/dist/entry-auth-delegated.d.mts +36 -0
- package/dist/entry-auth-delegated.mjs +27 -0
- package/dist/entry-auth-delegated.mjs.map +1 -0
- package/dist/entry-auth-none.cjs +4 -0
- package/dist/entry-auth-none.d.cts +25 -0
- package/dist/entry-auth-none.d.mts +25 -0
- package/dist/entry-auth-none.mjs +2 -0
- package/dist/entry-authorization-delegated.cjs +27 -0
- package/dist/entry-authorization-delegated.cjs.map +1 -0
- package/dist/entry-authorization-delegated.d.cts +31 -0
- package/dist/entry-authorization-delegated.d.mts +31 -0
- package/dist/entry-authorization-delegated.mjs +26 -0
- package/dist/entry-authorization-delegated.mjs.map +1 -0
- package/dist/entry-authorization-none.cjs +3 -0
- package/dist/entry-authorization-none.d.cts +18 -0
- package/dist/entry-authorization-none.d.mts +18 -0
- package/dist/entry-authorization-none.mjs +2 -0
- package/dist/entry-authorization-roles.cjs +6 -0
- package/dist/entry-authorization-roles.d.cts +65 -0
- package/dist/entry-authorization-roles.d.mts +65 -0
- package/dist/entry-authorization-roles.mjs +2 -0
- package/dist/entry-bun.cjs +24 -0
- package/dist/entry-bun.cjs.map +1 -0
- package/dist/entry-bun.d.cts +8 -0
- package/dist/entry-bun.d.mts +8 -0
- package/dist/entry-bun.mjs +23 -0
- package/dist/entry-bun.mjs.map +1 -0
- package/dist/entry-drizzle-mysql.cjs +20 -0
- package/dist/entry-drizzle-mysql.cjs.map +1 -0
- package/dist/entry-drizzle-mysql.d.cts +27 -0
- package/dist/entry-drizzle-mysql.d.mts +27 -0
- package/dist/entry-drizzle-mysql.mjs +19 -0
- package/dist/entry-drizzle-mysql.mjs.map +1 -0
- package/dist/entry-drizzle-pg.cjs +21 -0
- package/dist/entry-drizzle-pg.cjs.map +1 -0
- package/dist/entry-drizzle-pg.d.cts +26 -0
- package/dist/entry-drizzle-pg.d.mts +26 -0
- package/dist/entry-drizzle-pg.mjs +20 -0
- package/dist/entry-drizzle-pg.mjs.map +1 -0
- package/dist/entry-drizzle-sqlite.cjs +21 -0
- package/dist/entry-drizzle-sqlite.cjs.map +1 -0
- package/dist/entry-drizzle-sqlite.d.cts +23 -0
- package/dist/entry-drizzle-sqlite.d.mts +23 -0
- package/dist/entry-drizzle-sqlite.mjs +20 -0
- package/dist/entry-drizzle-sqlite.mjs.map +1 -0
- package/dist/entry-elysia.cjs +125 -0
- package/dist/entry-elysia.cjs.map +1 -0
- package/dist/entry-elysia.d.cts +1017 -0
- package/dist/entry-elysia.d.mts +1017 -0
- package/dist/entry-elysia.mjs +123 -0
- package/dist/entry-elysia.mjs.map +1 -0
- package/dist/entry-express.cjs +57 -0
- package/dist/entry-express.cjs.map +1 -0
- package/dist/entry-express.d.cts +15 -0
- package/dist/entry-express.d.mts +15 -0
- package/dist/entry-express.mjs +56 -0
- package/dist/entry-express.mjs.map +1 -0
- package/dist/entry-hono.cjs +35 -0
- package/dist/entry-hono.cjs.map +1 -0
- package/dist/entry-hono.d.cts +16 -0
- package/dist/entry-hono.d.mts +16 -0
- package/dist/entry-hono.mjs +34 -0
- package/dist/entry-hono.mjs.map +1 -0
- package/dist/entry-hooks-log.cjs +22 -0
- package/dist/entry-hooks-log.cjs.map +1 -0
- package/dist/entry-hooks-log.d.cts +23 -0
- package/dist/entry-hooks-log.d.mts +23 -0
- package/dist/entry-hooks-log.mjs +21 -0
- package/dist/entry-hooks-log.mjs.map +1 -0
- package/dist/entry-storage-cloudflare-kv.cjs +47 -0
- package/dist/entry-storage-cloudflare-kv.cjs.map +1 -0
- package/dist/entry-storage-cloudflare-kv.d.cts +42 -0
- package/dist/entry-storage-cloudflare-kv.d.mts +42 -0
- package/dist/entry-storage-cloudflare-kv.mjs +46 -0
- package/dist/entry-storage-cloudflare-kv.mjs.map +1 -0
- package/dist/entry-storage-drizzle.cjs +78 -0
- package/dist/entry-storage-drizzle.cjs.map +1 -0
- package/dist/entry-storage-drizzle.d.cts +30 -0
- package/dist/entry-storage-drizzle.d.mts +30 -0
- package/dist/entry-storage-drizzle.mjs +77 -0
- package/dist/entry-storage-drizzle.mjs.map +1 -0
- package/dist/entry-storage-file.cjs +4 -0
- package/dist/entry-storage-file.d.cts +30 -0
- package/dist/entry-storage-file.d.mts +30 -0
- package/dist/entry-storage-file.mjs +2 -0
- package/dist/entry-storage-libsql.cjs +3 -0
- package/dist/entry-storage-libsql.d.cts +48 -0
- package/dist/entry-storage-libsql.d.mts +48 -0
- package/dist/entry-storage-libsql.mjs +2 -0
- package/dist/entry-storage-memory.cjs +3 -0
- package/dist/entry-storage-memory.d.cts +2 -0
- package/dist/entry-storage-memory.d.mts +2 -0
- package/dist/entry-storage-memory.mjs +2 -0
- package/dist/entry-storage-mongodb.cjs +3 -0
- package/dist/entry-storage-mongodb.d.cts +55 -0
- package/dist/entry-storage-mongodb.d.mts +55 -0
- package/dist/entry-storage-mongodb.mjs +2 -0
- package/dist/entry-storage-postgres.cjs +3 -0
- package/dist/entry-storage-postgres.d.cts +62 -0
- package/dist/entry-storage-postgres.d.mts +62 -0
- package/dist/entry-storage-postgres.mjs +2 -0
- package/dist/entry-storage-redis.cjs +4 -0
- package/dist/entry-storage-redis.d.cts +77 -0
- package/dist/entry-storage-redis.d.mts +77 -0
- package/dist/entry-storage-redis.mjs +2 -0
- package/dist/entry-storage-sqlite.cjs +3 -0
- package/dist/entry-storage-sqlite.d.cts +36 -0
- package/dist/entry-storage-sqlite.d.mts +36 -0
- package/dist/entry-storage-sqlite.mjs +2 -0
- package/dist/entry-storage-unstorage.cjs +42 -0
- package/dist/entry-storage-unstorage.cjs.map +1 -0
- package/dist/entry-storage-unstorage.d.cts +29 -0
- package/dist/entry-storage-unstorage.d.mts +29 -0
- package/dist/entry-storage-unstorage.mjs +41 -0
- package/dist/entry-storage-unstorage.mjs.map +1 -0
- package/dist/file-COBYZA4Q.cjs +148 -0
- package/dist/file-COBYZA4Q.cjs.map +1 -0
- package/dist/file-fi02eFHk.mjs +131 -0
- package/dist/file-fi02eFHk.mjs.map +1 -0
- package/dist/index.cjs +123 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +368 -0
- package/dist/index.d.mts +366 -0
- package/dist/index.mjs +61 -0
- package/dist/index.mjs.map +1 -0
- package/dist/keys-Byyj4quQ.mjs +111 -0
- package/dist/keys-Byyj4quQ.mjs.map +1 -0
- package/dist/keys-FiKpaVHX.cjs +302 -0
- package/dist/keys-FiKpaVHX.cjs.map +1 -0
- package/dist/libsql-bpVi0bXN.mjs +113 -0
- package/dist/libsql-bpVi0bXN.mjs.map +1 -0
- package/dist/libsql-pPJEo1e4.cjs +124 -0
- package/dist/libsql-pPJEo1e4.cjs.map +1 -0
- package/dist/memory-8Ef-PL5a.cjs +137 -0
- package/dist/memory-8Ef-PL5a.cjs.map +1 -0
- package/dist/memory-BMsSSwqn.mjs +127 -0
- package/dist/memory-BMsSSwqn.mjs.map +1 -0
- package/dist/memory-FnMJWCmB.d.cts +28 -0
- package/dist/memory-qIvANEs_.d.mts +28 -0
- package/dist/mongodb-Cy8yo0uk.cjs +108 -0
- package/dist/mongodb-Cy8yo0uk.cjs.map +1 -0
- package/dist/mongodb-Ddaq9mml.mjs +97 -0
- package/dist/mongodb-Ddaq9mml.mjs.map +1 -0
- package/dist/none-BnZtaGNJ.mjs +23 -0
- package/dist/none-BnZtaGNJ.mjs.map +1 -0
- package/dist/none-CAsxCOWN.cjs +49 -0
- package/dist/none-CAsxCOWN.cjs.map +1 -0
- package/dist/none-CZVrfnmF.cjs +33 -0
- package/dist/none-CZVrfnmF.cjs.map +1 -0
- package/dist/none-GhVIoh_s.mjs +33 -0
- package/dist/none-GhVIoh_s.mjs.map +1 -0
- package/dist/postgres-C8WbchFa.cjs +134 -0
- package/dist/postgres-C8WbchFa.cjs.map +1 -0
- package/dist/postgres-c3pAhmhr.mjs +123 -0
- package/dist/postgres-c3pAhmhr.mjs.map +1 -0
- package/dist/react.css +1 -0
- package/dist/react.js +31465 -0
- package/dist/receiver.cjs +43 -0
- package/dist/receiver.cjs.map +1 -0
- package/dist/receiver.d.cts +36 -0
- package/dist/receiver.d.mts +36 -0
- package/dist/receiver.mjs +40 -0
- package/dist/receiver.mjs.map +1 -0
- package/dist/redis-CFJkuSgB.cjs +270 -0
- package/dist/redis-CFJkuSgB.cjs.map +1 -0
- package/dist/redis-CvLi0KF7.mjs +254 -0
- package/dist/redis-CvLi0KF7.mjs.map +1 -0
- package/dist/roles-D0G9XqBq.cjs +128 -0
- package/dist/roles-D0G9XqBq.cjs.map +1 -0
- package/dist/roles-vp361lTk.mjs +99 -0
- package/dist/roles-vp361lTk.mjs.map +1 -0
- package/dist/schema-mo__wv4P.d.cts +233 -0
- package/dist/schema-mo__wv4P.d.mts +233 -0
- package/dist/schema.cjs +13 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +2 -0
- package/dist/schema.d.mts +2 -0
- package/dist/schema.mjs +11 -0
- package/dist/schema.mjs.map +1 -0
- package/dist/signing.cjs +162 -0
- package/dist/signing.cjs.map +1 -0
- package/dist/signing.d.cts +73 -0
- package/dist/signing.d.mts +73 -0
- package/dist/signing.mjs +156 -0
- package/dist/signing.mjs.map +1 -0
- package/dist/sqlite-Cmqnrjes.mjs +67 -0
- package/dist/sqlite-Cmqnrjes.mjs.map +1 -0
- package/dist/sqlite-Dcufk0x3.cjs +78 -0
- package/dist/sqlite-Dcufk0x3.cjs.map +1 -0
- package/dist/table-Ce3Tzwqs.d.cts +11 -0
- package/dist/table-Ce3Tzwqs.d.mts +11 -0
- package/dist/testing.cjs +134 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +80 -0
- package/dist/testing.d.mts +80 -0
- package/dist/testing.mjs +131 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/types-react/react.d.ts +98 -0
- package/dist/types-react/schema.d.ts +229 -0
- package/dist/types-react/ui/App.d.ts +22 -0
- package/dist/types-react/ui/api.d.ts +97 -0
- package/dist/types-react/ui/components/JsonCodeEditor.d.ts +12 -0
- package/dist/types-react/ui/components/ThemeToggle.d.ts +2 -0
- package/dist/types-react/ui/components/Toast.d.ts +16 -0
- package/dist/types-react/ui/components/primitives.d.ts +50 -0
- package/dist/types-react/ui/components/ui-bits.d.ts +22 -0
- package/dist/types-react/ui/components/webhook-bits.d.ts +51 -0
- package/dist/types-react/ui/lib/format.d.ts +39 -0
- package/dist/types-react/ui/lib/nav-guard.d.ts +20 -0
- package/dist/types-react/ui/lib/utils.d.ts +3 -0
- package/dist/types-react/ui/theme.d.ts +12 -0
- package/dist/types-react/ui/types.d.ts +80 -0
- package/dist/types-react/ui/views/AuditView.d.ts +6 -0
- package/dist/types-react/ui/views/DeliveriesView.d.ts +12 -0
- package/dist/types-react/ui/views/EndpointsView.d.ts +11 -0
- package/dist/types-react/ui/views/EventTypesView.d.ts +11 -0
- package/dist/types-react/ui/views/MessagesView.d.ts +10 -0
- package/dist/types-react/ui/views/OverviewView.d.ts +12 -0
- package/dist/ui/assets/index-B0eoQX2U.css +1 -0
- package/dist/ui/assets/index-S5t_CLOe.js +209 -0
- package/dist/ui/index.html +14 -0
- package/package.json +487 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __exportAll = (all, no_symbols) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
+
key = keys[i];
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
21
|
+
get: ((k) => from[k]).bind(null, key),
|
|
22
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
28
|
+
value: mod,
|
|
29
|
+
enumerable: true
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/keys.ts
|
|
33
|
+
var keys_exports = /* @__PURE__ */ __exportAll({
|
|
34
|
+
RESERVED_APPLICATION_KEYS: () => RESERVED_APPLICATION_KEYS,
|
|
35
|
+
ROOT: () => "whk",
|
|
36
|
+
applicationMetaKey: () => applicationMetaKey,
|
|
37
|
+
applicationPrefix: () => applicationPrefix,
|
|
38
|
+
applicationsKey: () => applicationsKey,
|
|
39
|
+
attemptKey: () => attemptKey,
|
|
40
|
+
attemptsPrefix: () => attemptsPrefix,
|
|
41
|
+
auditLogKey: () => auditLogKey,
|
|
42
|
+
byEndpointKey: () => byEndpointKey,
|
|
43
|
+
byEndpointPrefix: () => byEndpointPrefix,
|
|
44
|
+
byMessageKey: () => byMessageKey,
|
|
45
|
+
byMessagePrefix: () => byMessagePrefix,
|
|
46
|
+
deliveriesPrefix: () => deliveriesPrefix,
|
|
47
|
+
deliveryKey: () => deliveryKey,
|
|
48
|
+
dueKey: () => dueKey,
|
|
49
|
+
duePrefix: () => duePrefix,
|
|
50
|
+
endpointKey: () => endpointKey,
|
|
51
|
+
endpointsKey: () => endpointsKey,
|
|
52
|
+
eventTypeKey: () => eventTypeKey,
|
|
53
|
+
eventTypesKey: () => eventTypesKey,
|
|
54
|
+
globalAuditLogKey: () => globalAuditLogKey,
|
|
55
|
+
idempotencyKey: () => idempotencyKey,
|
|
56
|
+
lastSegment: () => lastSegment,
|
|
57
|
+
messageKey: () => messageKey,
|
|
58
|
+
messagesPrefix: () => messagesPrefix,
|
|
59
|
+
parseDueKey: () => parseDueKey
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Application keys that would collide with global index keys under the shared
|
|
63
|
+
* root. Rejected by validation.
|
|
64
|
+
*/
|
|
65
|
+
const RESERVED_APPLICATION_KEYS = [
|
|
66
|
+
"applications",
|
|
67
|
+
"event-types",
|
|
68
|
+
"audit-log"
|
|
69
|
+
];
|
|
70
|
+
/** Global audit log (event-type actions, which are not application-scoped). */
|
|
71
|
+
const globalAuditLogKey = () => `whk/audit-log`;
|
|
72
|
+
/** Index key listing all known application keys. */
|
|
73
|
+
const applicationsKey = () => `whk/applications`;
|
|
74
|
+
/** Metadata for a single application. */
|
|
75
|
+
const applicationMetaKey = (applicationKey) => `whk/${applicationKey}/metadata`;
|
|
76
|
+
/** Index key listing all event type names (global catalog). */
|
|
77
|
+
const eventTypesKey = () => `whk/event-types`;
|
|
78
|
+
/** A single event type record. */
|
|
79
|
+
const eventTypeKey = (name) => `whk/event-types/${name}`;
|
|
80
|
+
/** Index key listing an application's endpoint ids. */
|
|
81
|
+
const endpointsKey = (applicationKey) => `whk/${applicationKey}/endpoints`;
|
|
82
|
+
/** A single endpoint record. */
|
|
83
|
+
const endpointKey = (applicationKey, endpointId) => `whk/${applicationKey}/endpoints/${endpointId}`;
|
|
84
|
+
/** Prefix under which an application's messages live. */
|
|
85
|
+
const messagesPrefix = (applicationKey) => `whk/${applicationKey}/messages/`;
|
|
86
|
+
/** A single message record. */
|
|
87
|
+
const messageKey = (applicationKey, messageId) => `${messagesPrefix(applicationKey)}${messageId}`;
|
|
88
|
+
/** Maps a caller-supplied idempotency key to the message id it produced. */
|
|
89
|
+
const idempotencyKey = (applicationKey, key) => `whk/${applicationKey}/idempotency/${key}`;
|
|
90
|
+
/** Prefix under which an application's deliveries live. */
|
|
91
|
+
const deliveriesPrefix = (applicationKey) => `whk/${applicationKey}/deliveries/`;
|
|
92
|
+
/** A single delivery record. */
|
|
93
|
+
const deliveryKey = (applicationKey, deliveryId) => `${deliveriesPrefix(applicationKey)}${deliveryId}`;
|
|
94
|
+
/** Prefix under which one delivery's attempts live. */
|
|
95
|
+
const attemptsPrefix = (applicationKey, deliveryId) => `whk/${applicationKey}/attempts/${deliveryId}/`;
|
|
96
|
+
/**
|
|
97
|
+
* A single attempt record. The attempt number is zero-padded to four digits so
|
|
98
|
+
* lexicographic key order equals attempt order.
|
|
99
|
+
*/
|
|
100
|
+
const attemptKey = (applicationKey, deliveryId, attemptNumber) => `${attemptsPrefix(applicationKey, deliveryId)}${String(attemptNumber).padStart(4, "0")}`;
|
|
101
|
+
/** Prefix of an application's due index (the dispatcher's work queue). */
|
|
102
|
+
const duePrefix = (applicationKey) => `whk/${applicationKey}/due/`;
|
|
103
|
+
/**
|
|
104
|
+
* A due-index entry: 13-digit zero-padded epoch milliseconds, then the delivery
|
|
105
|
+
* id, `~`-separated. Sorting keys lexicographically sorts entries chronologically.
|
|
106
|
+
*/
|
|
107
|
+
const dueKey = (applicationKey, dueAtMillis, deliveryId) => `${duePrefix(applicationKey)}${String(dueAtMillis).padStart(13, "0")}~${deliveryId}`;
|
|
108
|
+
/** Parse a due-index key back into its due-time and delivery id. */
|
|
109
|
+
const parseDueKey = (key) => {
|
|
110
|
+
const last = lastSegment(key);
|
|
111
|
+
const sep = last.indexOf("~");
|
|
112
|
+
if (sep === -1) return null;
|
|
113
|
+
const millis = Number(last.slice(0, sep));
|
|
114
|
+
const deliveryId = last.slice(sep + 1);
|
|
115
|
+
if (!Number.isFinite(millis) || deliveryId.length === 0) return null;
|
|
116
|
+
return {
|
|
117
|
+
dueAtMillis: millis,
|
|
118
|
+
deliveryId
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/** Prefix of the message → deliveries reverse index. */
|
|
122
|
+
const byMessagePrefix = (applicationKey, messageId) => `whk/${applicationKey}/by-message/${messageId}/`;
|
|
123
|
+
/** One entry in the message → deliveries reverse index. */
|
|
124
|
+
const byMessageKey = (applicationKey, messageId, deliveryId) => `${byMessagePrefix(applicationKey, messageId)}${deliveryId}`;
|
|
125
|
+
/** Prefix of the endpoint → deliveries reverse index. */
|
|
126
|
+
const byEndpointPrefix = (applicationKey, endpointId) => `whk/${applicationKey}/by-endpoint/${endpointId}/`;
|
|
127
|
+
/** One entry in the endpoint → deliveries reverse index. */
|
|
128
|
+
const byEndpointKey = (applicationKey, endpointId, deliveryId) => `${byEndpointPrefix(applicationKey, endpointId)}${deliveryId}`;
|
|
129
|
+
/** Append-only audit log for an application, stored as an ordered `AuditEntry[]`. */
|
|
130
|
+
const auditLogKey = (applicationKey) => `whk/${applicationKey}/audit-log`;
|
|
131
|
+
/** Prefix under which everything belonging to one application lives. */
|
|
132
|
+
const applicationPrefix = (applicationKey) => `whk/${applicationKey}/`;
|
|
133
|
+
/** Extract the trailing segment (endpoint id / message id / …) from a key. */
|
|
134
|
+
const lastSegment = (key) => {
|
|
135
|
+
const parts = key.split("/");
|
|
136
|
+
return parts[parts.length - 1] ?? "";
|
|
137
|
+
};
|
|
138
|
+
//#endregion
|
|
139
|
+
Object.defineProperty(exports, "RESERVED_APPLICATION_KEYS", {
|
|
140
|
+
enumerable: true,
|
|
141
|
+
get: function() {
|
|
142
|
+
return RESERVED_APPLICATION_KEYS;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(exports, "__exportAll", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function() {
|
|
148
|
+
return __exportAll;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
Object.defineProperty(exports, "__toESM", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
get: function() {
|
|
154
|
+
return __toESM;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
Object.defineProperty(exports, "applicationMetaKey", {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
get: function() {
|
|
160
|
+
return applicationMetaKey;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
Object.defineProperty(exports, "applicationPrefix", {
|
|
164
|
+
enumerable: true,
|
|
165
|
+
get: function() {
|
|
166
|
+
return applicationPrefix;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
Object.defineProperty(exports, "applicationsKey", {
|
|
170
|
+
enumerable: true,
|
|
171
|
+
get: function() {
|
|
172
|
+
return applicationsKey;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
Object.defineProperty(exports, "attemptKey", {
|
|
176
|
+
enumerable: true,
|
|
177
|
+
get: function() {
|
|
178
|
+
return attemptKey;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
Object.defineProperty(exports, "attemptsPrefix", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
get: function() {
|
|
184
|
+
return attemptsPrefix;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
Object.defineProperty(exports, "auditLogKey", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
get: function() {
|
|
190
|
+
return auditLogKey;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(exports, "byEndpointKey", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
get: function() {
|
|
196
|
+
return byEndpointKey;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
Object.defineProperty(exports, "byEndpointPrefix", {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
get: function() {
|
|
202
|
+
return byEndpointPrefix;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
Object.defineProperty(exports, "byMessageKey", {
|
|
206
|
+
enumerable: true,
|
|
207
|
+
get: function() {
|
|
208
|
+
return byMessageKey;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
Object.defineProperty(exports, "byMessagePrefix", {
|
|
212
|
+
enumerable: true,
|
|
213
|
+
get: function() {
|
|
214
|
+
return byMessagePrefix;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
Object.defineProperty(exports, "deliveriesPrefix", {
|
|
218
|
+
enumerable: true,
|
|
219
|
+
get: function() {
|
|
220
|
+
return deliveriesPrefix;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
Object.defineProperty(exports, "deliveryKey", {
|
|
224
|
+
enumerable: true,
|
|
225
|
+
get: function() {
|
|
226
|
+
return deliveryKey;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
Object.defineProperty(exports, "dueKey", {
|
|
230
|
+
enumerable: true,
|
|
231
|
+
get: function() {
|
|
232
|
+
return dueKey;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
Object.defineProperty(exports, "endpointKey", {
|
|
236
|
+
enumerable: true,
|
|
237
|
+
get: function() {
|
|
238
|
+
return endpointKey;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
Object.defineProperty(exports, "endpointsKey", {
|
|
242
|
+
enumerable: true,
|
|
243
|
+
get: function() {
|
|
244
|
+
return endpointsKey;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
Object.defineProperty(exports, "eventTypeKey", {
|
|
248
|
+
enumerable: true,
|
|
249
|
+
get: function() {
|
|
250
|
+
return eventTypeKey;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
Object.defineProperty(exports, "eventTypesKey", {
|
|
254
|
+
enumerable: true,
|
|
255
|
+
get: function() {
|
|
256
|
+
return eventTypesKey;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
Object.defineProperty(exports, "globalAuditLogKey", {
|
|
260
|
+
enumerable: true,
|
|
261
|
+
get: function() {
|
|
262
|
+
return globalAuditLogKey;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
Object.defineProperty(exports, "idempotencyKey", {
|
|
266
|
+
enumerable: true,
|
|
267
|
+
get: function() {
|
|
268
|
+
return idempotencyKey;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
Object.defineProperty(exports, "keys_exports", {
|
|
272
|
+
enumerable: true,
|
|
273
|
+
get: function() {
|
|
274
|
+
return keys_exports;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
Object.defineProperty(exports, "lastSegment", {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function() {
|
|
280
|
+
return lastSegment;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
Object.defineProperty(exports, "messageKey", {
|
|
284
|
+
enumerable: true,
|
|
285
|
+
get: function() {
|
|
286
|
+
return messageKey;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
Object.defineProperty(exports, "messagesPrefix", {
|
|
290
|
+
enumerable: true,
|
|
291
|
+
get: function() {
|
|
292
|
+
return messagesPrefix;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
Object.defineProperty(exports, "parseDueKey", {
|
|
296
|
+
enumerable: true,
|
|
297
|
+
get: function() {
|
|
298
|
+
return parseDueKey;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
//# sourceMappingURL=keys-FiKpaVHX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys-FiKpaVHX.cjs","names":[],"sources":["../src/keys.ts"],"sourcesContent":["/**\n * Storage key layout for `@xtandard/webhooks`.\n *\n * Keys are namespaced by application so a single storage backend can host the\n * whole control plane. Pure string helpers — no dependencies.\n *\n * ```txt\n * whk/applications -> string[] index\n * whk/{app}/metadata -> Application\n * whk/event-types -> string[] index (global)\n * whk/event-types/{name} -> EventType\n * whk/{app}/endpoints -> string[] index\n * whk/{app}/endpoints/{id} -> Endpoint\n * whk/{app}/messages/{id} -> Message\n * whk/{app}/idempotency/{key} -> message id\n * whk/{app}/deliveries/{id} -> Delivery\n * whk/{app}/attempts/{deliveryId}/{n} -> DeliveryAttempt (n zero-padded)\n * whk/{app}/due/{dueAtMillis}~{deliveryId} -> DueEntry (13-digit zero-padded millis)\n * whk/{app}/by-message/{messageId}/{deliveryId} -> 1 (reverse index)\n * whk/{app}/by-endpoint/{endpointId}/{deliveryId} -> 1 (reverse index)\n * whk/{app}/audit-log -> AuditEntry[] (single ordered array)\n * ```\n *\n * The due index is the dispatcher's generic work queue: 13-digit zero-padded\n * milliseconds make lexicographic key order chronological, so a sorted\n * `getKeys(duePrefix(app))` scan yields deliveries in due order.\n *\n * @module\n */\n\n/** Root namespace segment for all keys. */\nexport const ROOT = \"whk\";\n\n/**\n * Application keys that would collide with global index keys under the shared\n * root. Rejected by validation.\n */\nexport const RESERVED_APPLICATION_KEYS = [\"applications\", \"event-types\", \"audit-log\"] as const;\n\n/** Global audit log (event-type actions, which are not application-scoped). */\nexport const globalAuditLogKey = () => `${ROOT}/audit-log`;\n\n/** Index key listing all known application keys. */\nexport const applicationsKey = () => `${ROOT}/applications`;\n\n/** Metadata for a single application. */\nexport const applicationMetaKey = (applicationKey: string) => `${ROOT}/${applicationKey}/metadata`;\n\n/** Index key listing all event type names (global catalog). */\nexport const eventTypesKey = () => `${ROOT}/event-types`;\n\n/** A single event type record. */\nexport const eventTypeKey = (name: string) => `${ROOT}/event-types/${name}`;\n\n/** Index key listing an application's endpoint ids. */\nexport const endpointsKey = (applicationKey: string) => `${ROOT}/${applicationKey}/endpoints`;\n\n/** A single endpoint record. */\nexport const endpointKey = (applicationKey: string, endpointId: string) =>\n `${ROOT}/${applicationKey}/endpoints/${endpointId}`;\n\n/** Prefix under which an application's messages live. */\nexport const messagesPrefix = (applicationKey: string) => `${ROOT}/${applicationKey}/messages/`;\n\n/** A single message record. */\nexport const messageKey = (applicationKey: string, messageId: string) =>\n `${messagesPrefix(applicationKey)}${messageId}`;\n\n/** Maps a caller-supplied idempotency key to the message id it produced. */\nexport const idempotencyKey = (applicationKey: string, key: string) =>\n `${ROOT}/${applicationKey}/idempotency/${key}`;\n\n/** Prefix under which an application's deliveries live. */\nexport const deliveriesPrefix = (applicationKey: string) => `${ROOT}/${applicationKey}/deliveries/`;\n\n/** A single delivery record. */\nexport const deliveryKey = (applicationKey: string, deliveryId: string) =>\n `${deliveriesPrefix(applicationKey)}${deliveryId}`;\n\n/** Prefix under which one delivery's attempts live. */\nexport const attemptsPrefix = (applicationKey: string, deliveryId: string) =>\n `${ROOT}/${applicationKey}/attempts/${deliveryId}/`;\n\n/**\n * A single attempt record. The attempt number is zero-padded to four digits so\n * lexicographic key order equals attempt order.\n */\nexport const attemptKey = (applicationKey: string, deliveryId: string, attemptNumber: number) =>\n `${attemptsPrefix(applicationKey, deliveryId)}${String(attemptNumber).padStart(4, \"0\")}`;\n\n/** Prefix of an application's due index (the dispatcher's work queue). */\nexport const duePrefix = (applicationKey: string) => `${ROOT}/${applicationKey}/due/`;\n\n/** Value stored at a due-index key. */\nexport interface DueEntry {\n app: string;\n deliveryId: string;\n}\n\n/**\n * A due-index entry: 13-digit zero-padded epoch milliseconds, then the delivery\n * id, `~`-separated. Sorting keys lexicographically sorts entries chronologically.\n */\nexport const dueKey = (applicationKey: string, dueAtMillis: number, deliveryId: string) =>\n `${duePrefix(applicationKey)}${String(dueAtMillis).padStart(13, \"0\")}~${deliveryId}`;\n\n/** Parse a due-index key back into its due-time and delivery id. */\nexport const parseDueKey = (key: string): { dueAtMillis: number; deliveryId: string } | null => {\n const last = lastSegment(key);\n const sep = last.indexOf(\"~\");\n if (sep === -1) return null;\n const millis = Number(last.slice(0, sep));\n const deliveryId = last.slice(sep + 1);\n if (!Number.isFinite(millis) || deliveryId.length === 0) return null;\n return { dueAtMillis: millis, deliveryId };\n};\n\n/** Prefix of the message → deliveries reverse index. */\nexport const byMessagePrefix = (applicationKey: string, messageId: string) =>\n `${ROOT}/${applicationKey}/by-message/${messageId}/`;\n\n/** One entry in the message → deliveries reverse index. */\nexport const byMessageKey = (applicationKey: string, messageId: string, deliveryId: string) =>\n `${byMessagePrefix(applicationKey, messageId)}${deliveryId}`;\n\n/** Prefix of the endpoint → deliveries reverse index. */\nexport const byEndpointPrefix = (applicationKey: string, endpointId: string) =>\n `${ROOT}/${applicationKey}/by-endpoint/${endpointId}/`;\n\n/** One entry in the endpoint → deliveries reverse index. */\nexport const byEndpointKey = (applicationKey: string, endpointId: string, deliveryId: string) =>\n `${byEndpointPrefix(applicationKey, endpointId)}${deliveryId}`;\n\n/** Append-only audit log for an application, stored as an ordered `AuditEntry[]`. */\nexport const auditLogKey = (applicationKey: string) => `${ROOT}/${applicationKey}/audit-log`;\n\n/** Prefix under which everything belonging to one application lives. */\nexport const applicationPrefix = (applicationKey: string) => `${ROOT}/${applicationKey}/`;\n\n/** Extract the trailing segment (endpoint id / message id / …) from a key. */\nexport const lastSegment = (key: string): string => {\n const parts = key.split(\"/\");\n return parts[parts.length - 1] ?? \"\";\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,4BAA4B;CAAC;CAAgB;CAAe;AAAW;;AAGpF,MAAa,0BAA0B;;AAGvC,MAAa,wBAAwB;;AAGrC,MAAa,sBAAsB,mBAA2B,OAAW,eAAe;;AAGxF,MAAa,sBAAsB;;AAGnC,MAAa,gBAAgB,SAAiB,mBAAuB;;AAGrE,MAAa,gBAAgB,mBAA2B,OAAW,eAAe;;AAGlF,MAAa,eAAe,gBAAwB,eAClD,OAAW,eAAe,aAAa;;AAGzC,MAAa,kBAAkB,mBAA2B,OAAW,eAAe;;AAGpF,MAAa,cAAc,gBAAwB,cACjD,GAAG,eAAe,cAAc,IAAI;;AAGtC,MAAa,kBAAkB,gBAAwB,QACrD,OAAW,eAAe,eAAe;;AAG3C,MAAa,oBAAoB,mBAA2B,OAAW,eAAe;;AAGtF,MAAa,eAAe,gBAAwB,eAClD,GAAG,iBAAiB,cAAc,IAAI;;AAGxC,MAAa,kBAAkB,gBAAwB,eACrD,OAAW,eAAe,YAAY,WAAW;;;;;AAMnD,MAAa,cAAc,gBAAwB,YAAoB,kBACrE,GAAG,eAAe,gBAAgB,UAAU,IAAI,OAAO,aAAa,EAAE,SAAS,GAAG,GAAG;;AAGvF,MAAa,aAAa,mBAA2B,OAAW,eAAe;;;;;AAY/E,MAAa,UAAU,gBAAwB,aAAqB,eAClE,GAAG,UAAU,cAAc,IAAI,OAAO,WAAW,EAAE,SAAS,IAAI,GAAG,EAAE,GAAG;;AAG1E,MAAa,eAAe,QAAoE;CAC9F,MAAM,OAAO,YAAY,GAAG;CAC5B,MAAM,MAAM,KAAK,QAAQ,GAAG;CAC5B,IAAI,QAAQ,IAAI,OAAO;CACvB,MAAM,SAAS,OAAO,KAAK,MAAM,GAAG,GAAG,CAAC;CACxC,MAAM,aAAa,KAAK,MAAM,MAAM,CAAC;CACrC,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,WAAW,WAAW,GAAG,OAAO;CAChE,OAAO;EAAE,aAAa;EAAQ;CAAW;AAC3C;;AAGA,MAAa,mBAAmB,gBAAwB,cACtD,OAAW,eAAe,cAAc,UAAU;;AAGpD,MAAa,gBAAgB,gBAAwB,WAAmB,eACtE,GAAG,gBAAgB,gBAAgB,SAAS,IAAI;;AAGlD,MAAa,oBAAoB,gBAAwB,eACvD,OAAW,eAAe,eAAe,WAAW;;AAGtD,MAAa,iBAAiB,gBAAwB,YAAoB,eACxE,GAAG,iBAAiB,gBAAgB,UAAU,IAAI;;AAGpD,MAAa,eAAe,mBAA2B,OAAW,eAAe;;AAGjF,MAAa,qBAAqB,mBAA2B,OAAW,eAAe;;AAGvF,MAAa,eAAe,QAAwB;CAClD,MAAM,QAAQ,IAAI,MAAM,GAAG;CAC3B,OAAO,MAAM,MAAM,SAAS,MAAM;AACpC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-D7D4PA-g.mjs";
|
|
2
|
+
import { a as requirePeer } from "./contract-BEhDcd_5.mjs";
|
|
3
|
+
//#region src/storage/libsql.ts
|
|
4
|
+
/**
|
|
5
|
+
* libSQL / [Turso](https://turso.tech) storage adapter built on the
|
|
6
|
+
* [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) package
|
|
7
|
+
* (an optional peer dependency). It speaks the same SQL dialect as SQLite but
|
|
8
|
+
* works against a **remote, replicated, edge-distributed** database — or a local
|
|
9
|
+
* file / embedded replica — so it suits multi-node and edge runtimes where
|
|
10
|
+
* `bun:sqlite` (single-file, Bun-only) does not.
|
|
11
|
+
*
|
|
12
|
+
* Pass either a pre-constructed `client`, or `url` (+ optional `authToken`) to let
|
|
13
|
+
* the adapter construct one lazily on first use. An optional `prefix` is **not**
|
|
14
|
+
* used here — keys are stored verbatim as the primary key; namespace via a
|
|
15
|
+
* distinct `table` or a separate database instead.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
|
|
19
|
+
*
|
|
20
|
+
* // Turso (remote):
|
|
21
|
+
* const storage = createLibsqlStorage({
|
|
22
|
+
* url: process.env.TURSO_DATABASE_URL!, // libsql://<db>-<org>.turso.io
|
|
23
|
+
* authToken: process.env.TURSO_AUTH_TOKEN!,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Local file or embedded replica:
|
|
27
|
+
* // const storage = createLibsqlStorage({ url: "file:webhooks.db" });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
var libsql_exports = /* @__PURE__ */ __exportAll({ createLibsqlStorage: () => createLibsqlStorage });
|
|
33
|
+
const escapeLike = (prefix) => prefix.replace(/[\\%_]/g, (c) => `\\${c}`);
|
|
34
|
+
/**
|
|
35
|
+
* Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created
|
|
36
|
+
* on first use; connection (when constructed from `url`) is lazy and shared.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
|
|
41
|
+
*
|
|
42
|
+
* const storage = createLibsqlStorage({
|
|
43
|
+
* url: process.env.TURSO_DATABASE_URL!,
|
|
44
|
+
* authToken: process.env.TURSO_AUTH_TOKEN,
|
|
45
|
+
* });
|
|
46
|
+
* // process.on("SIGTERM", () => storage.close());
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
function createLibsqlStorage(options) {
|
|
50
|
+
const table = options.table ?? "xtandard_webhooks";
|
|
51
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) throw new Error(`Invalid table name: ${JSON.stringify(table)}`);
|
|
52
|
+
const ownsClient = !options.client;
|
|
53
|
+
let client = options.client;
|
|
54
|
+
let ready;
|
|
55
|
+
/** Resolve a connected client and ensure the table exists (once). */
|
|
56
|
+
function getClient() {
|
|
57
|
+
ready ??= (async () => {
|
|
58
|
+
if (!client) {
|
|
59
|
+
if (!options.url) throw new Error("createLibsqlStorage requires either a `client` or a `url`");
|
|
60
|
+
let createClient;
|
|
61
|
+
try {
|
|
62
|
+
const specifier = "@libsql/client";
|
|
63
|
+
({createClient} = await import(specifier));
|
|
64
|
+
} catch {
|
|
65
|
+
requirePeer("@libsql/client", "storage/libsql");
|
|
66
|
+
}
|
|
67
|
+
client = createClient({
|
|
68
|
+
url: options.url,
|
|
69
|
+
authToken: options.authToken
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
await client.execute(`CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`);
|
|
73
|
+
return client;
|
|
74
|
+
})();
|
|
75
|
+
return ready;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
async getItem(key) {
|
|
79
|
+
const { rows } = await (await getClient()).execute({
|
|
80
|
+
sql: `SELECT value FROM ${table} WHERE key = ?`,
|
|
81
|
+
args: [key]
|
|
82
|
+
});
|
|
83
|
+
const value = rows[0]?.value;
|
|
84
|
+
return typeof value === "string" ? JSON.parse(value) : null;
|
|
85
|
+
},
|
|
86
|
+
async setItem(key, value) {
|
|
87
|
+
await (await getClient()).execute({
|
|
88
|
+
sql: `INSERT INTO ${table} (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
|
|
89
|
+
args: [key, JSON.stringify(value)]
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
async removeItem(key) {
|
|
93
|
+
await (await getClient()).execute({
|
|
94
|
+
sql: `DELETE FROM ${table} WHERE key = ?`,
|
|
95
|
+
args: [key]
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
async getKeys(prefix) {
|
|
99
|
+
const { rows } = await (await getClient()).execute({
|
|
100
|
+
sql: `SELECT key FROM ${table} WHERE key LIKE ? ESCAPE '\\'`,
|
|
101
|
+
args: [`${escapeLike(prefix)}%`]
|
|
102
|
+
});
|
|
103
|
+
return rows.map((r) => String(r.key));
|
|
104
|
+
},
|
|
105
|
+
close() {
|
|
106
|
+
if (ownsClient) client?.close();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { libsql_exports as n, createLibsqlStorage as t };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=libsql-bpVi0bXN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"libsql-bpVi0bXN.mjs","names":[],"sources":["../src/storage/libsql.ts"],"sourcesContent":["/**\n * libSQL / [Turso](https://turso.tech) storage adapter built on the\n * [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) package\n * (an optional peer dependency). It speaks the same SQL dialect as SQLite but\n * works against a **remote, replicated, edge-distributed** database — or a local\n * file / embedded replica — so it suits multi-node and edge runtimes where\n * `bun:sqlite` (single-file, Bun-only) does not.\n *\n * Pass either a pre-constructed `client`, or `url` (+ optional `authToken`) to let\n * the adapter construct one lazily on first use. An optional `prefix` is **not**\n * used here — keys are stored verbatim as the primary key; namespace via a\n * distinct `table` or a separate database instead.\n *\n * ```ts\n * import { createLibsqlStorage } from \"@xtandard/webhooks/storage/libsql\";\n *\n * // Turso (remote):\n * const storage = createLibsqlStorage({\n * url: process.env.TURSO_DATABASE_URL!, // libsql://<db>-<org>.turso.io\n * authToken: process.env.TURSO_AUTH_TOKEN!,\n * });\n *\n * // Local file or embedded replica:\n * // const storage = createLibsqlStorage({ url: \"file:webhooks.db\" });\n * ```\n *\n * @module\n */\n\nimport { requirePeer } from \"./contract.ts\";\nimport type { WebhooksStorage } from \"./contract.ts\";\n\n/** Options for {@link createLibsqlStorage}. */\nexport interface LibsqlStorageOptions {\n /** libSQL connection URL (`libsql://…`, `https://…`, `file:…`, `:memory:`). Used when no `client`. */\n url?: string;\n /** Turso auth token for remote databases. */\n authToken?: string;\n /** A pre-constructed `@libsql/client` client to use instead of connecting. */\n client?: LibsqlClientLike;\n /** Table name (default `\"xtandard_webhooks\"`). Validated as a safe identifier. */\n table?: string;\n}\n\n/** A {@link WebhooksStorage} backed by libSQL/Turso, plus `close()`. */\nexport interface LibsqlWebhooksStorage extends WebhooksStorage {\n /** Close the client if this adapter created it; no-op for a borrowed instance. */\n close(): void;\n}\n\n/** Minimal structural view of the `@libsql/client` surface this adapter uses. */\nexport interface LibsqlClientLike {\n execute(\n stmt: string | { sql: string; args: unknown[] },\n ): Promise<{ rows: Array<Record<string, unknown>> }>;\n close(): void;\n}\n\nconst escapeLike = (prefix: string): string => prefix.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n\n/**\n * Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created\n * on first use; connection (when constructed from `url`) is lazy and shared.\n *\n * @example\n * ```ts\n * import { createLibsqlStorage } from \"@xtandard/webhooks/storage/libsql\";\n *\n * const storage = createLibsqlStorage({\n * url: process.env.TURSO_DATABASE_URL!,\n * authToken: process.env.TURSO_AUTH_TOKEN,\n * });\n * // process.on(\"SIGTERM\", () => storage.close());\n * ```\n */\nexport function createLibsqlStorage(options: LibsqlStorageOptions): LibsqlWebhooksStorage {\n const table = options.table ?? \"xtandard_webhooks\";\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {\n throw new Error(`Invalid table name: ${JSON.stringify(table)}`);\n }\n\n const ownsClient = !options.client;\n let client: LibsqlClientLike | undefined = options.client;\n let ready: Promise<LibsqlClientLike> | undefined;\n\n /** Resolve a connected client and ensure the table exists (once). */\n function getClient(): Promise<LibsqlClientLike> {\n ready ??= (async () => {\n if (!client) {\n if (!options.url) {\n throw new Error(\"createLibsqlStorage requires either a `client` or a `url`\");\n }\n let createClient: (opts: { url: string; authToken?: string }) => LibsqlClientLike;\n try {\n // Non-literal specifier so the type-checker doesn't require the optional\n // peer to be installed at build time (it's resolved at runtime only).\n const specifier: string = \"@libsql/client\";\n ({ createClient } = (await import(specifier)) as {\n createClient: (opts: { url: string; authToken?: string }) => LibsqlClientLike;\n });\n } catch {\n requirePeer(\"@libsql/client\", \"storage/libsql\");\n }\n client = createClient({ url: options.url, authToken: options.authToken });\n }\n await client.execute(\n `CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,\n );\n return client;\n })();\n return ready;\n }\n\n return {\n async getItem<T>(key: string): Promise<T | null> {\n const c = await getClient();\n const { rows } = await c.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const value = rows[0]?.value;\n return typeof value === \"string\" ? (JSON.parse(value) as T) : null;\n },\n\n async setItem<T>(key: string, value: T): Promise<void> {\n const c = await getClient();\n await c.execute({\n sql: `INSERT INTO ${table} (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,\n args: [key, JSON.stringify(value)],\n });\n },\n\n async removeItem(key: string): Promise<void> {\n const c = await getClient();\n await c.execute({ sql: `DELETE FROM ${table} WHERE key = ?`, args: [key] });\n },\n\n async getKeys(prefix: string): Promise<string[]> {\n const c = await getClient();\n const { rows } = await c.execute({\n sql: `SELECT key FROM ${table} WHERE key LIKE ? ESCAPE '\\\\'`,\n args: [`${escapeLike(prefix)}%`],\n });\n return rows.map((r) => String(r.key));\n },\n\n close(): void {\n if (ownsClient) client?.close();\n },\n } satisfies LibsqlWebhooksStorage;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,MAAM,cAAc,WAA2B,OAAO,QAAQ,YAAY,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;AAiBxF,SAAgB,oBAAoB,SAAsD;CACxF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,CAAC,2BAA2B,KAAK,KAAK,GACxC,MAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,KAAK,GAAG;CAGhE,MAAM,aAAa,CAAC,QAAQ;CAC5B,IAAI,SAAuC,QAAQ;CACnD,IAAI;;CAGJ,SAAS,YAAuC;EAC9C,WAAW,YAAY;GACrB,IAAI,CAAC,QAAQ;IACX,IAAI,CAAC,QAAQ,KACX,MAAM,IAAI,MAAM,2DAA2D;IAE7E,IAAI;IACJ,IAAI;KAGF,MAAM,YAAoB;KAC1B,CAAC,CAAE,gBAAkB,MAAM,OAAO;IAGpC,QAAQ;KACN,YAAY,kBAAkB,gBAAgB;IAChD;IACA,SAAS,aAAa;KAAE,KAAK,QAAQ;KAAK,WAAW,QAAQ;IAAU,CAAC;GAC1E;GACA,MAAM,OAAO,QACX,8BAA8B,MAAM,6CACtC;GACA,OAAO;EACT,GAAG;EACH,OAAO;CACT;CAEA,OAAO;EACL,MAAM,QAAW,KAAgC;GAE/C,MAAM,EAAE,SAAS,OAAM,MADP,UAAU,GACD,QAAQ;IAC/B,KAAK,qBAAqB,MAAM;IAChC,MAAM,CAAC,GAAG;GACZ,CAAC;GACD,MAAM,QAAQ,KAAK,IAAI;GACvB,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAAU;EAChE;EAEA,MAAM,QAAW,KAAa,OAAyB;GAErD,OAAM,MADU,UAAU,GAClB,QAAQ;IACd,KAAK,eAAe,MAAM;IAC1B,MAAM,CAAC,KAAK,KAAK,UAAU,KAAK,CAAC;GACnC,CAAC;EACH;EAEA,MAAM,WAAW,KAA4B;GAE3C,OAAM,MADU,UAAU,GAClB,QAAQ;IAAE,KAAK,eAAe,MAAM;IAAiB,MAAM,CAAC,GAAG;GAAE,CAAC;EAC5E;EAEA,MAAM,QAAQ,QAAmC;GAE/C,MAAM,EAAE,SAAS,OAAM,MADP,UAAU,GACD,QAAQ;IAC/B,KAAK,mBAAmB,MAAM;IAC9B,MAAM,CAAC,GAAG,WAAW,MAAM,EAAE,EAAE;GACjC,CAAC;GACD,OAAO,KAAK,KAAK,MAAM,OAAO,EAAE,GAAG,CAAC;EACtC;EAEA,QAAc;GACZ,IAAI,YAAY,QAAQ,MAAM;EAChC;CACF;AACF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const require_keys = require("./keys-FiKpaVHX.cjs");
|
|
2
|
+
const require_contract = require("./contract-Bf1qguwt.cjs");
|
|
3
|
+
//#region src/storage/libsql.ts
|
|
4
|
+
/**
|
|
5
|
+
* libSQL / [Turso](https://turso.tech) storage adapter built on the
|
|
6
|
+
* [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) package
|
|
7
|
+
* (an optional peer dependency). It speaks the same SQL dialect as SQLite but
|
|
8
|
+
* works against a **remote, replicated, edge-distributed** database — or a local
|
|
9
|
+
* file / embedded replica — so it suits multi-node and edge runtimes where
|
|
10
|
+
* `bun:sqlite` (single-file, Bun-only) does not.
|
|
11
|
+
*
|
|
12
|
+
* Pass either a pre-constructed `client`, or `url` (+ optional `authToken`) to let
|
|
13
|
+
* the adapter construct one lazily on first use. An optional `prefix` is **not**
|
|
14
|
+
* used here — keys are stored verbatim as the primary key; namespace via a
|
|
15
|
+
* distinct `table` or a separate database instead.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
|
|
19
|
+
*
|
|
20
|
+
* // Turso (remote):
|
|
21
|
+
* const storage = createLibsqlStorage({
|
|
22
|
+
* url: process.env.TURSO_DATABASE_URL!, // libsql://<db>-<org>.turso.io
|
|
23
|
+
* authToken: process.env.TURSO_AUTH_TOKEN!,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Local file or embedded replica:
|
|
27
|
+
* // const storage = createLibsqlStorage({ url: "file:webhooks.db" });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
var libsql_exports = /* @__PURE__ */ require_keys.__exportAll({ createLibsqlStorage: () => createLibsqlStorage });
|
|
33
|
+
const escapeLike = (prefix) => prefix.replace(/[\\%_]/g, (c) => `\\${c}`);
|
|
34
|
+
/**
|
|
35
|
+
* Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created
|
|
36
|
+
* on first use; connection (when constructed from `url`) is lazy and shared.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { createLibsqlStorage } from "@xtandard/webhooks/storage/libsql";
|
|
41
|
+
*
|
|
42
|
+
* const storage = createLibsqlStorage({
|
|
43
|
+
* url: process.env.TURSO_DATABASE_URL!,
|
|
44
|
+
* authToken: process.env.TURSO_AUTH_TOKEN,
|
|
45
|
+
* });
|
|
46
|
+
* // process.on("SIGTERM", () => storage.close());
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
function createLibsqlStorage(options) {
|
|
50
|
+
const table = options.table ?? "xtandard_webhooks";
|
|
51
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) throw new Error(`Invalid table name: ${JSON.stringify(table)}`);
|
|
52
|
+
const ownsClient = !options.client;
|
|
53
|
+
let client = options.client;
|
|
54
|
+
let ready;
|
|
55
|
+
/** Resolve a connected client and ensure the table exists (once). */
|
|
56
|
+
function getClient() {
|
|
57
|
+
ready ??= (async () => {
|
|
58
|
+
if (!client) {
|
|
59
|
+
if (!options.url) throw new Error("createLibsqlStorage requires either a `client` or a `url`");
|
|
60
|
+
let createClient;
|
|
61
|
+
try {
|
|
62
|
+
const specifier = "@libsql/client";
|
|
63
|
+
({createClient} = await import(specifier));
|
|
64
|
+
} catch {
|
|
65
|
+
require_contract.requirePeer("@libsql/client", "storage/libsql");
|
|
66
|
+
}
|
|
67
|
+
client = createClient({
|
|
68
|
+
url: options.url,
|
|
69
|
+
authToken: options.authToken
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
await client.execute(`CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`);
|
|
73
|
+
return client;
|
|
74
|
+
})();
|
|
75
|
+
return ready;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
async getItem(key) {
|
|
79
|
+
const { rows } = await (await getClient()).execute({
|
|
80
|
+
sql: `SELECT value FROM ${table} WHERE key = ?`,
|
|
81
|
+
args: [key]
|
|
82
|
+
});
|
|
83
|
+
const value = rows[0]?.value;
|
|
84
|
+
return typeof value === "string" ? JSON.parse(value) : null;
|
|
85
|
+
},
|
|
86
|
+
async setItem(key, value) {
|
|
87
|
+
await (await getClient()).execute({
|
|
88
|
+
sql: `INSERT INTO ${table} (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
|
|
89
|
+
args: [key, JSON.stringify(value)]
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
async removeItem(key) {
|
|
93
|
+
await (await getClient()).execute({
|
|
94
|
+
sql: `DELETE FROM ${table} WHERE key = ?`,
|
|
95
|
+
args: [key]
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
async getKeys(prefix) {
|
|
99
|
+
const { rows } = await (await getClient()).execute({
|
|
100
|
+
sql: `SELECT key FROM ${table} WHERE key LIKE ? ESCAPE '\\'`,
|
|
101
|
+
args: [`${escapeLike(prefix)}%`]
|
|
102
|
+
});
|
|
103
|
+
return rows.map((r) => String(r.key));
|
|
104
|
+
},
|
|
105
|
+
close() {
|
|
106
|
+
if (ownsClient) client?.close();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
Object.defineProperty(exports, "createLibsqlStorage", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
get: function() {
|
|
114
|
+
return createLibsqlStorage;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(exports, "libsql_exports", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function() {
|
|
120
|
+
return libsql_exports;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=libsql-pPJEo1e4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"libsql-pPJEo1e4.cjs","names":[],"sources":["../src/storage/libsql.ts"],"sourcesContent":["/**\n * libSQL / [Turso](https://turso.tech) storage adapter built on the\n * [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) package\n * (an optional peer dependency). It speaks the same SQL dialect as SQLite but\n * works against a **remote, replicated, edge-distributed** database — or a local\n * file / embedded replica — so it suits multi-node and edge runtimes where\n * `bun:sqlite` (single-file, Bun-only) does not.\n *\n * Pass either a pre-constructed `client`, or `url` (+ optional `authToken`) to let\n * the adapter construct one lazily on first use. An optional `prefix` is **not**\n * used here — keys are stored verbatim as the primary key; namespace via a\n * distinct `table` or a separate database instead.\n *\n * ```ts\n * import { createLibsqlStorage } from \"@xtandard/webhooks/storage/libsql\";\n *\n * // Turso (remote):\n * const storage = createLibsqlStorage({\n * url: process.env.TURSO_DATABASE_URL!, // libsql://<db>-<org>.turso.io\n * authToken: process.env.TURSO_AUTH_TOKEN!,\n * });\n *\n * // Local file or embedded replica:\n * // const storage = createLibsqlStorage({ url: \"file:webhooks.db\" });\n * ```\n *\n * @module\n */\n\nimport { requirePeer } from \"./contract.ts\";\nimport type { WebhooksStorage } from \"./contract.ts\";\n\n/** Options for {@link createLibsqlStorage}. */\nexport interface LibsqlStorageOptions {\n /** libSQL connection URL (`libsql://…`, `https://…`, `file:…`, `:memory:`). Used when no `client`. */\n url?: string;\n /** Turso auth token for remote databases. */\n authToken?: string;\n /** A pre-constructed `@libsql/client` client to use instead of connecting. */\n client?: LibsqlClientLike;\n /** Table name (default `\"xtandard_webhooks\"`). Validated as a safe identifier. */\n table?: string;\n}\n\n/** A {@link WebhooksStorage} backed by libSQL/Turso, plus `close()`. */\nexport interface LibsqlWebhooksStorage extends WebhooksStorage {\n /** Close the client if this adapter created it; no-op for a borrowed instance. */\n close(): void;\n}\n\n/** Minimal structural view of the `@libsql/client` surface this adapter uses. */\nexport interface LibsqlClientLike {\n execute(\n stmt: string | { sql: string; args: unknown[] },\n ): Promise<{ rows: Array<Record<string, unknown>> }>;\n close(): void;\n}\n\nconst escapeLike = (prefix: string): string => prefix.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n\n/**\n * Create a libSQL/Turso-backed {@link LibsqlWebhooksStorage}. The table is created\n * on first use; connection (when constructed from `url`) is lazy and shared.\n *\n * @example\n * ```ts\n * import { createLibsqlStorage } from \"@xtandard/webhooks/storage/libsql\";\n *\n * const storage = createLibsqlStorage({\n * url: process.env.TURSO_DATABASE_URL!,\n * authToken: process.env.TURSO_AUTH_TOKEN,\n * });\n * // process.on(\"SIGTERM\", () => storage.close());\n * ```\n */\nexport function createLibsqlStorage(options: LibsqlStorageOptions): LibsqlWebhooksStorage {\n const table = options.table ?? \"xtandard_webhooks\";\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {\n throw new Error(`Invalid table name: ${JSON.stringify(table)}`);\n }\n\n const ownsClient = !options.client;\n let client: LibsqlClientLike | undefined = options.client;\n let ready: Promise<LibsqlClientLike> | undefined;\n\n /** Resolve a connected client and ensure the table exists (once). */\n function getClient(): Promise<LibsqlClientLike> {\n ready ??= (async () => {\n if (!client) {\n if (!options.url) {\n throw new Error(\"createLibsqlStorage requires either a `client` or a `url`\");\n }\n let createClient: (opts: { url: string; authToken?: string }) => LibsqlClientLike;\n try {\n // Non-literal specifier so the type-checker doesn't require the optional\n // peer to be installed at build time (it's resolved at runtime only).\n const specifier: string = \"@libsql/client\";\n ({ createClient } = (await import(specifier)) as {\n createClient: (opts: { url: string; authToken?: string }) => LibsqlClientLike;\n });\n } catch {\n requirePeer(\"@libsql/client\", \"storage/libsql\");\n }\n client = createClient({ url: options.url, authToken: options.authToken });\n }\n await client.execute(\n `CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,\n );\n return client;\n })();\n return ready;\n }\n\n return {\n async getItem<T>(key: string): Promise<T | null> {\n const c = await getClient();\n const { rows } = await c.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const value = rows[0]?.value;\n return typeof value === \"string\" ? (JSON.parse(value) as T) : null;\n },\n\n async setItem<T>(key: string, value: T): Promise<void> {\n const c = await getClient();\n await c.execute({\n sql: `INSERT INTO ${table} (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,\n args: [key, JSON.stringify(value)],\n });\n },\n\n async removeItem(key: string): Promise<void> {\n const c = await getClient();\n await c.execute({ sql: `DELETE FROM ${table} WHERE key = ?`, args: [key] });\n },\n\n async getKeys(prefix: string): Promise<string[]> {\n const c = await getClient();\n const { rows } = await c.execute({\n sql: `SELECT key FROM ${table} WHERE key LIKE ? ESCAPE '\\\\'`,\n args: [`${escapeLike(prefix)}%`],\n });\n return rows.map((r) => String(r.key));\n },\n\n close(): void {\n if (ownsClient) client?.close();\n },\n } satisfies LibsqlWebhooksStorage;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,MAAM,cAAc,WAA2B,OAAO,QAAQ,YAAY,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;AAiBxF,SAAgB,oBAAoB,SAAsD;CACxF,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,CAAC,2BAA2B,KAAK,KAAK,GACxC,MAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,KAAK,GAAG;CAGhE,MAAM,aAAa,CAAC,QAAQ;CAC5B,IAAI,SAAuC,QAAQ;CACnD,IAAI;;CAGJ,SAAS,YAAuC;EAC9C,WAAW,YAAY;GACrB,IAAI,CAAC,QAAQ;IACX,IAAI,CAAC,QAAQ,KACX,MAAM,IAAI,MAAM,2DAA2D;IAE7E,IAAI;IACJ,IAAI;KAGF,MAAM,YAAoB;KAC1B,CAAC,CAAE,gBAAkB,MAAM,OAAO;IAGpC,QAAQ;KACN,iBAAA,YAAY,kBAAkB,gBAAgB;IAChD;IACA,SAAS,aAAa;KAAE,KAAK,QAAQ;KAAK,WAAW,QAAQ;IAAU,CAAC;GAC1E;GACA,MAAM,OAAO,QACX,8BAA8B,MAAM,6CACtC;GACA,OAAO;EACT,GAAG;EACH,OAAO;CACT;CAEA,OAAO;EACL,MAAM,QAAW,KAAgC;GAE/C,MAAM,EAAE,SAAS,OAAM,MADP,UAAU,GACD,QAAQ;IAC/B,KAAK,qBAAqB,MAAM;IAChC,MAAM,CAAC,GAAG;GACZ,CAAC;GACD,MAAM,QAAQ,KAAK,IAAI;GACvB,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAAU;EAChE;EAEA,MAAM,QAAW,KAAa,OAAyB;GAErD,OAAM,MADU,UAAU,GAClB,QAAQ;IACd,KAAK,eAAe,MAAM;IAC1B,MAAM,CAAC,KAAK,KAAK,UAAU,KAAK,CAAC;GACnC,CAAC;EACH;EAEA,MAAM,WAAW,KAA4B;GAE3C,OAAM,MADU,UAAU,GAClB,QAAQ;IAAE,KAAK,eAAe,MAAM;IAAiB,MAAM,CAAC,GAAG;GAAE,CAAC;EAC5E;EAEA,MAAM,QAAQ,QAAmC;GAE/C,MAAM,EAAE,SAAS,OAAM,MADP,UAAU,GACD,QAAQ;IAC/B,KAAK,mBAAmB,MAAM;IAC9B,MAAM,CAAC,GAAG,WAAW,MAAM,EAAE,EAAE;GACjC,CAAC;GACD,OAAO,KAAK,KAAK,MAAM,OAAO,EAAE,GAAG,CAAC;EACtC;EAEA,QAAc;GACZ,IAAI,YAAY,QAAQ,MAAM;EAChC;CACF;AACF"}
|