@adriangalilea/utils 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/bot/access-control.d.ts.map +1 -1
- package/dist/bot/access-control.js +17 -1
- package/dist/bot/access-control.js.map +1 -1
- package/dist/bot/allow-list.d.ts +38 -0
- package/dist/bot/allow-list.d.ts.map +1 -0
- package/dist/bot/allow-list.js +41 -0
- package/dist/bot/allow-list.js.map +1 -0
- package/dist/bot/callbacks.d.ts +89 -0
- package/dist/bot/callbacks.d.ts.map +1 -0
- package/dist/bot/callbacks.js +128 -0
- package/dist/bot/callbacks.js.map +1 -0
- package/dist/bot/ctx.d.ts +219 -0
- package/dist/bot/ctx.d.ts.map +1 -0
- package/dist/bot/ctx.js +52 -0
- package/dist/bot/ctx.js.map +1 -0
- package/dist/bot/index.d.ts +4 -0
- package/dist/bot/index.d.ts.map +1 -1
- package/dist/bot/index.js +4 -0
- package/dist/bot/index.js.map +1 -1
- package/dist/bot/kit.d.ts +1 -1
- package/dist/bot/kit.d.ts.map +1 -1
- package/dist/bot/kit.js +4 -2
- package/dist/bot/kit.js.map +1 -1
- package/dist/bot/menu.d.ts +23 -1
- package/dist/bot/menu.d.ts.map +1 -1
- package/dist/bot/menu.js +30 -1
- package/dist/bot/menu.js.map +1 -1
- package/dist/bot/payments/callbacks.d.ts +28 -0
- package/dist/bot/payments/callbacks.d.ts.map +1 -0
- package/dist/bot/payments/callbacks.js +102 -0
- package/dist/bot/payments/callbacks.js.map +1 -0
- package/dist/bot/payments/commands.d.ts +26 -0
- package/dist/bot/payments/commands.d.ts.map +1 -0
- package/dist/bot/payments/commands.js +41 -0
- package/dist/bot/payments/commands.js.map +1 -0
- package/dist/bot/payments/config.d.ts +30 -0
- package/dist/bot/payments/config.d.ts.map +1 -0
- package/dist/bot/payments/config.js +166 -0
- package/dist/bot/payments/config.js.map +1 -0
- package/dist/bot/payments/derive.d.ts +75 -0
- package/dist/bot/payments/derive.d.ts.map +1 -0
- package/dist/bot/payments/derive.js +151 -0
- package/dist/bot/payments/derive.js.map +1 -0
- package/dist/bot/payments/handlers.d.ts +113 -0
- package/dist/bot/payments/handlers.d.ts.map +1 -0
- package/dist/bot/payments/handlers.js +284 -0
- package/dist/bot/payments/handlers.js.map +1 -0
- package/dist/bot/payments/index.d.ts +17 -0
- package/dist/bot/payments/index.d.ts.map +1 -0
- package/dist/bot/payments/index.js +14 -0
- package/dist/bot/payments/index.js.map +1 -0
- package/dist/bot/payments/invoice.d.ts +101 -0
- package/dist/bot/payments/invoice.d.ts.map +1 -0
- package/dist/bot/payments/invoice.js +213 -0
- package/dist/bot/payments/invoice.js.map +1 -0
- package/dist/bot/payments/menu-item.d.ts +41 -0
- package/dist/bot/payments/menu-item.d.ts.map +1 -0
- package/dist/bot/payments/menu-item.js +259 -0
- package/dist/bot/payments/menu-item.js.map +1 -0
- package/dist/bot/payments/payload.d.ts +42 -0
- package/dist/bot/payments/payload.d.ts.map +1 -0
- package/dist/bot/payments/payload.js +69 -0
- package/dist/bot/payments/payload.js.map +1 -0
- package/dist/bot/payments/payouts.d.ts +88 -0
- package/dist/bot/payments/payouts.d.ts.map +1 -0
- package/dist/bot/payments/payouts.js +133 -0
- package/dist/bot/payments/payouts.js.map +1 -0
- package/dist/bot/payments/plugin.d.ts +271 -0
- package/dist/bot/payments/plugin.d.ts.map +1 -0
- package/dist/bot/payments/plugin.js +141 -0
- package/dist/bot/payments/plugin.js.map +1 -0
- package/dist/bot/payments/refund.d.ts +124 -0
- package/dist/bot/payments/refund.d.ts.map +1 -0
- package/dist/bot/payments/refund.js +308 -0
- package/dist/bot/payments/refund.js.map +1 -0
- package/dist/bot/payments/schemas.d.ts +58 -0
- package/dist/bot/payments/schemas.d.ts.map +1 -0
- package/dist/bot/payments/schemas.js +55 -0
- package/dist/bot/payments/schemas.js.map +1 -0
- package/dist/bot/payments/state.d.ts +90 -0
- package/dist/bot/payments/state.d.ts.map +1 -0
- package/dist/bot/payments/state.js +149 -0
- package/dist/bot/payments/state.js.map +1 -0
- package/dist/bot/payments/stores.d.ts +44 -0
- package/dist/bot/payments/stores.d.ts.map +1 -0
- package/dist/bot/payments/stores.js +39 -0
- package/dist/bot/payments/stores.js.map +1 -0
- package/dist/bot/payments/types.d.ts +299 -0
- package/dist/bot/payments/types.d.ts.map +1 -0
- package/dist/bot/payments/types.js +39 -0
- package/dist/bot/payments/types.js.map +1 -0
- package/dist/bot/payments/waiver.d.ts +81 -0
- package/dist/bot/payments/waiver.d.ts.map +1 -0
- package/dist/bot/payments/waiver.js +145 -0
- package/dist/bot/payments/waiver.js.map +1 -0
- package/dist/bot/storage.d.ts +154 -0
- package/dist/bot/storage.d.ts.map +1 -0
- package/dist/bot/storage.js +222 -0
- package/dist/bot/storage.js.map +1 -0
- package/package.json +28 -3
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed storage abstraction for `bot/*` plugins.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the per-plugin `botSubKey + storage.get/set` boilerplate
|
|
5
|
+
* with three small primitives that automatically:
|
|
6
|
+
*
|
|
7
|
+
* - **Namespace by bot id.** Every key gets `bot-<id>:` prefixed via
|
|
8
|
+
* `ctx.bot.info.id`, so multiple bots sharing one Redis stay
|
|
9
|
+
* isolated by construction (see `bot/CLAUDE.md` § Multi-bot
|
|
10
|
+
* isolation). No plugin has to remember to wrap.
|
|
11
|
+
*
|
|
12
|
+
* - **Validate on read** (optional). Pass any `{ parse(data:
|
|
13
|
+
* unknown): T }` validator (zod / valibot / arktype / yours) and a
|
|
14
|
+
* mis-shaped record from storage throws a clear `SourcedError`
|
|
15
|
+
* instead of NaN-ing downstream. Omit the validator and you get
|
|
16
|
+
* the same untyped read as before.
|
|
17
|
+
*
|
|
18
|
+
* - **Stay typed end-to-end.** `botRecord<ChargeRecord>(...)` returns
|
|
19
|
+
* a `BotRecord<ChargeRecord>` and `.get()` is `Promise<ChargeRecord
|
|
20
|
+
* | undefined>`. No casts at the call site.
|
|
21
|
+
*
|
|
22
|
+
* ## Three primitives
|
|
23
|
+
*
|
|
24
|
+
* - `botRecord<T>(storage, prefix, validator?)` — get/set/delete a
|
|
25
|
+
* single typed value keyed by an id (`pay:charge:<chargeId>`,
|
|
26
|
+
* `ac:user:<userId>`, …). Most plugin state.
|
|
27
|
+
*
|
|
28
|
+
* - `botIndex(storage, prefix, opts?)` — a capped, prepend-friendly
|
|
29
|
+
* `string[]` stored under a single key. Use for "recent N
|
|
30
|
+
* charges", "pending access requests", etc.
|
|
31
|
+
*
|
|
32
|
+
* - `botSentinel(storage, prefix)` — a presence flag (`"1"` / absent)
|
|
33
|
+
* for idempotency. `claim(ctx, id)` returns `true` only on first
|
|
34
|
+
* call; subsequent calls return `false` without setting. Note:
|
|
35
|
+
* read-then-write is NOT atomic under concurrent load; for
|
|
36
|
+
* production we'd want a storage backend with `setNX` semantics.
|
|
37
|
+
*
|
|
38
|
+
* ## Why not couple to zod?
|
|
39
|
+
*
|
|
40
|
+
* The validator parameter is typed as `{ parse(data: unknown): T }` —
|
|
41
|
+
* a structural shape that zod schemas, valibot, ArkType, and hand-rolled
|
|
42
|
+
* type guards all satisfy. The library has zero zod imports; consumers
|
|
43
|
+
* bring whichever validator they prefer.
|
|
44
|
+
*/
|
|
45
|
+
import type { Storage } from "@gramio/storage";
|
|
46
|
+
import type { BotIdCtx } from "./ctx.js";
|
|
47
|
+
/**
|
|
48
|
+
* Anything with a synchronous `parse(unknown): T`. zod schemas satisfy
|
|
49
|
+
* this natively (`.parse` throws on invalid input). Custom guards work
|
|
50
|
+
* the same way: `{ parse: (d) => { if (!ok(d)) throw new Error(...); return d as T } }`.
|
|
51
|
+
*/
|
|
52
|
+
export type RecordValidator<T> = {
|
|
53
|
+
parse: (data: unknown) => T;
|
|
54
|
+
};
|
|
55
|
+
export type BotRecord<T> = {
|
|
56
|
+
/** Storage key for `id` under this record's prefix. */
|
|
57
|
+
keyFor: (ctx: BotIdCtx, id: string) => string;
|
|
58
|
+
/** `undefined` on miss; throws `SourcedError` on validator failure. */
|
|
59
|
+
get: (ctx: BotIdCtx, id: string) => Promise<T | undefined>;
|
|
60
|
+
/** Overwrites unconditionally. Use `botSentinel` if you need set-if-absent. */
|
|
61
|
+
set: (ctx: BotIdCtx, id: string, value: T) => Promise<void>;
|
|
62
|
+
/** Hard delete. No-op if absent. */
|
|
63
|
+
delete: (ctx: BotIdCtx, id: string) => Promise<void>;
|
|
64
|
+
/** `true` if a record exists at `id` (no read, no validation). */
|
|
65
|
+
has: (ctx: BotIdCtx, id: string) => Promise<boolean>;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Typed record store, auto-namespaced by bot id.
|
|
69
|
+
*
|
|
70
|
+
* @example per-charge record with zod validation
|
|
71
|
+
*
|
|
72
|
+
* const charges = botRecord<ChargeRecord>(
|
|
73
|
+
* storage,
|
|
74
|
+
* 'pay:charge',
|
|
75
|
+
* ChargeRecordSchema, // any zod.ZodType<ChargeRecord>
|
|
76
|
+
* )
|
|
77
|
+
* await charges.set(ctx, chargeId, charge)
|
|
78
|
+
* const c = await charges.get(ctx, chargeId)
|
|
79
|
+
*
|
|
80
|
+
* @example without a validator (backwards-compatible behaviour)
|
|
81
|
+
*
|
|
82
|
+
* const charges = botRecord<ChargeRecord>(storage, 'pay:charge')
|
|
83
|
+
* const c = await charges.get(ctx, chargeId) // typed but unchecked
|
|
84
|
+
*/
|
|
85
|
+
export declare const botRecord: <T>(storage: Storage, prefix: string, validator?: RecordValidator<T>) => BotRecord<T>;
|
|
86
|
+
export type BotIndexOptions = {
|
|
87
|
+
/**
|
|
88
|
+
* Maximum number of ids retained. New `prepend` calls past this
|
|
89
|
+
* limit drop the OLDEST id. Omit for an unbounded index (a
|
|
90
|
+
* footgun for high-volume bots — set a cap).
|
|
91
|
+
*/
|
|
92
|
+
capacity?: number;
|
|
93
|
+
};
|
|
94
|
+
export type BotIndex = {
|
|
95
|
+
keyFor: (ctx: BotIdCtx) => string;
|
|
96
|
+
/** Newest-first list of ids, capped to `capacity` if configured. */
|
|
97
|
+
list: (ctx: BotIdCtx) => Promise<string[]>;
|
|
98
|
+
/** Insert `id` at the front. Idempotent: re-prepending an existing
|
|
99
|
+
* id moves it to the front. Returns the new length post-cap. */
|
|
100
|
+
prepend: (ctx: BotIdCtx, id: string) => Promise<number>;
|
|
101
|
+
/** Remove `id`. No-op if absent. Returns whether anything was removed. */
|
|
102
|
+
remove: (ctx: BotIdCtx, id: string) => Promise<boolean>;
|
|
103
|
+
/** Wipe the whole index. */
|
|
104
|
+
clear: (ctx: BotIdCtx) => Promise<void>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Newest-first capped list of ids stored under a single key. Designed
|
|
108
|
+
* for "user's last N charges", "pending access requests", "recent
|
|
109
|
+
* payouts" — small, ordered, bounded.
|
|
110
|
+
*
|
|
111
|
+
* `prepend(id)` is the only mutator. Re-prepending an existing id moves
|
|
112
|
+
* it to the front (de-duplication). At-cap inserts drop the tail.
|
|
113
|
+
*/
|
|
114
|
+
export declare const botIndex: (storage: Storage, prefix: string, opts?: BotIndexOptions) => BotIndex;
|
|
115
|
+
export type BotSentinel = {
|
|
116
|
+
keyFor: (ctx: BotIdCtx, id: string) => string;
|
|
117
|
+
/**
|
|
118
|
+
* Attempt to claim `id`. Returns `true` on first claim (and
|
|
119
|
+
* persists), `false` if already claimed (no write).
|
|
120
|
+
*
|
|
121
|
+
* NOT atomic under concurrent load — the read and write happen as
|
|
122
|
+
* two ops. For at-most-once semantics under contention, swap the
|
|
123
|
+
* storage backend for one with `setNX` (e.g. `@gramio/storage-redis`
|
|
124
|
+
* with a `setIfNotExists` helper) and override this method. For
|
|
125
|
+
* single-process polling bots (the v1 target), the race window is
|
|
126
|
+
* bounded by Telegram's retry delay and acceptable.
|
|
127
|
+
*/
|
|
128
|
+
claim: (ctx: BotIdCtx, id: string) => Promise<boolean>;
|
|
129
|
+
/** `true` if `id` has been claimed. No write. */
|
|
130
|
+
check: (ctx: BotIdCtx, id: string) => Promise<boolean>;
|
|
131
|
+
/** Release a claim. Returns whether anything was released. */
|
|
132
|
+
release: (ctx: BotIdCtx, id: string) => Promise<boolean>;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Presence-flag store for idempotency. Each id is either claimed
|
|
136
|
+
* (storage has the key) or not (storage doesn't). The stored value is
|
|
137
|
+
* an opaque sentinel string — readers only care about presence.
|
|
138
|
+
*
|
|
139
|
+
* @example idempotent successful_payment fulfillment
|
|
140
|
+
*
|
|
141
|
+
* const idem = botSentinel(storage, 'pay:idem')
|
|
142
|
+
* if (!(await idem.claim(ctx, chargeId))) return // duplicate, no-op
|
|
143
|
+
* await fulfill(charge)
|
|
144
|
+
*/
|
|
145
|
+
export declare const botSentinel: (storage: Storage, prefix: string) => BotSentinel;
|
|
146
|
+
/**
|
|
147
|
+
* Wrap any `BotRecord` with trace-level logging for every read/write.
|
|
148
|
+
* Useful when debugging a specific plugin's storage flow without
|
|
149
|
+
* polluting every other plugin's logs. Defaults off.
|
|
150
|
+
*
|
|
151
|
+
* const charges = withTracing(botRecord<ChargeRecord>(...), 'pay:charge')
|
|
152
|
+
*/
|
|
153
|
+
export declare const withTracing: <T>(record: BotRecord<T>, label: string) => BotRecord<T>;
|
|
154
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/bot/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed storage abstraction for `bot/*` plugins.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the per-plugin `botSubKey + storage.get/set` boilerplate
|
|
5
|
+
* with three small primitives that automatically:
|
|
6
|
+
*
|
|
7
|
+
* - **Namespace by bot id.** Every key gets `bot-<id>:` prefixed via
|
|
8
|
+
* `ctx.bot.info.id`, so multiple bots sharing one Redis stay
|
|
9
|
+
* isolated by construction (see `bot/CLAUDE.md` § Multi-bot
|
|
10
|
+
* isolation). No plugin has to remember to wrap.
|
|
11
|
+
*
|
|
12
|
+
* - **Validate on read** (optional). Pass any `{ parse(data:
|
|
13
|
+
* unknown): T }` validator (zod / valibot / arktype / yours) and a
|
|
14
|
+
* mis-shaped record from storage throws a clear `SourcedError`
|
|
15
|
+
* instead of NaN-ing downstream. Omit the validator and you get
|
|
16
|
+
* the same untyped read as before.
|
|
17
|
+
*
|
|
18
|
+
* - **Stay typed end-to-end.** `botRecord<ChargeRecord>(...)` returns
|
|
19
|
+
* a `BotRecord<ChargeRecord>` and `.get()` is `Promise<ChargeRecord
|
|
20
|
+
* | undefined>`. No casts at the call site.
|
|
21
|
+
*
|
|
22
|
+
* ## Three primitives
|
|
23
|
+
*
|
|
24
|
+
* - `botRecord<T>(storage, prefix, validator?)` — get/set/delete a
|
|
25
|
+
* single typed value keyed by an id (`pay:charge:<chargeId>`,
|
|
26
|
+
* `ac:user:<userId>`, …). Most plugin state.
|
|
27
|
+
*
|
|
28
|
+
* - `botIndex(storage, prefix, opts?)` — a capped, prepend-friendly
|
|
29
|
+
* `string[]` stored under a single key. Use for "recent N
|
|
30
|
+
* charges", "pending access requests", etc.
|
|
31
|
+
*
|
|
32
|
+
* - `botSentinel(storage, prefix)` — a presence flag (`"1"` / absent)
|
|
33
|
+
* for idempotency. `claim(ctx, id)` returns `true` only on first
|
|
34
|
+
* call; subsequent calls return `false` without setting. Note:
|
|
35
|
+
* read-then-write is NOT atomic under concurrent load; for
|
|
36
|
+
* production we'd want a storage backend with `setNX` semantics.
|
|
37
|
+
*
|
|
38
|
+
* ## Why not couple to zod?
|
|
39
|
+
*
|
|
40
|
+
* The validator parameter is typed as `{ parse(data: unknown): T }` —
|
|
41
|
+
* a structural shape that zod schemas, valibot, ArkType, and hand-rolled
|
|
42
|
+
* type guards all satisfy. The library has zero zod imports; consumers
|
|
43
|
+
* bring whichever validator they prefer.
|
|
44
|
+
*/
|
|
45
|
+
import { SourcedError } from "../offensive.js";
|
|
46
|
+
import { createLogger } from "../universal/log.js";
|
|
47
|
+
const log = createLogger("bot/storage");
|
|
48
|
+
const botIdOf = (ctx) => {
|
|
49
|
+
const id = ctx.bot?.info?.id;
|
|
50
|
+
if (typeof id !== "number") {
|
|
51
|
+
throw new SourcedError({
|
|
52
|
+
source: "storage",
|
|
53
|
+
operation: "key",
|
|
54
|
+
message: "ctx.bot.info.id is missing — called before bot.start()/bot.init()?",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return id;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Build the namespaced key for a record / index / sentinel. Matches
|
|
61
|
+
* the format `botSubKey` / `botStorageKey` in `kit.ts` use, so the
|
|
62
|
+
* abstractions compose with anything that still consumes those.
|
|
63
|
+
*/
|
|
64
|
+
const buildKey = (ctx, prefix, id) => {
|
|
65
|
+
const base = `bot-${botIdOf(ctx)}:${prefix}`;
|
|
66
|
+
return id !== undefined ? `${base}:${id}` : base;
|
|
67
|
+
};
|
|
68
|
+
const parseOr = (raw, validator, key) => {
|
|
69
|
+
if (!validator)
|
|
70
|
+
return raw;
|
|
71
|
+
try {
|
|
72
|
+
return validator.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch (cause) {
|
|
75
|
+
throw new SourcedError({
|
|
76
|
+
source: "storage",
|
|
77
|
+
operation: "validate",
|
|
78
|
+
message: cause instanceof Error
|
|
79
|
+
? cause.message
|
|
80
|
+
: "validator threw a non-Error value",
|
|
81
|
+
cause,
|
|
82
|
+
context: { key },
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Typed record store, auto-namespaced by bot id.
|
|
88
|
+
*
|
|
89
|
+
* @example per-charge record with zod validation
|
|
90
|
+
*
|
|
91
|
+
* const charges = botRecord<ChargeRecord>(
|
|
92
|
+
* storage,
|
|
93
|
+
* 'pay:charge',
|
|
94
|
+
* ChargeRecordSchema, // any zod.ZodType<ChargeRecord>
|
|
95
|
+
* )
|
|
96
|
+
* await charges.set(ctx, chargeId, charge)
|
|
97
|
+
* const c = await charges.get(ctx, chargeId)
|
|
98
|
+
*
|
|
99
|
+
* @example without a validator (backwards-compatible behaviour)
|
|
100
|
+
*
|
|
101
|
+
* const charges = botRecord<ChargeRecord>(storage, 'pay:charge')
|
|
102
|
+
* const c = await charges.get(ctx, chargeId) // typed but unchecked
|
|
103
|
+
*/
|
|
104
|
+
export const botRecord = (storage, prefix, validator) => ({
|
|
105
|
+
keyFor: (ctx, id) => buildKey(ctx, prefix, id),
|
|
106
|
+
get: async (ctx, id) => {
|
|
107
|
+
const key = buildKey(ctx, prefix, id);
|
|
108
|
+
const raw = await storage.get(key);
|
|
109
|
+
if (raw === undefined)
|
|
110
|
+
return undefined;
|
|
111
|
+
return parseOr(raw, validator, key);
|
|
112
|
+
},
|
|
113
|
+
// `@gramio/storage`'s methods return `MaybePromise<T>` (sync- or
|
|
114
|
+
// async-storage agnostic). We normalize to `Promise<T>` via
|
|
115
|
+
// `Promise.resolve` so callers don't have to care which backend
|
|
116
|
+
// they're on.
|
|
117
|
+
set: async (ctx, id, value) => void (await storage.set(buildKey(ctx, prefix, id), value)),
|
|
118
|
+
delete: async (ctx, id) => void (await storage.delete(buildKey(ctx, prefix, id))),
|
|
119
|
+
has: async (ctx, id) => (await storage.has(buildKey(ctx, prefix, id))) === true,
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Newest-first capped list of ids stored under a single key. Designed
|
|
123
|
+
* for "user's last N charges", "pending access requests", "recent
|
|
124
|
+
* payouts" — small, ordered, bounded.
|
|
125
|
+
*
|
|
126
|
+
* `prepend(id)` is the only mutator. Re-prepending an existing id moves
|
|
127
|
+
* it to the front (de-duplication). At-cap inserts drop the tail.
|
|
128
|
+
*/
|
|
129
|
+
export const botIndex = (storage, prefix, opts = {}) => {
|
|
130
|
+
const cap = opts.capacity;
|
|
131
|
+
return {
|
|
132
|
+
keyFor: (ctx) => buildKey(ctx, prefix),
|
|
133
|
+
list: async (ctx) => {
|
|
134
|
+
const key = buildKey(ctx, prefix);
|
|
135
|
+
return (await storage.get(key)) ?? [];
|
|
136
|
+
},
|
|
137
|
+
prepend: async (ctx, id) => {
|
|
138
|
+
const key = buildKey(ctx, prefix);
|
|
139
|
+
const existing = (await storage.get(key)) ?? [];
|
|
140
|
+
// De-dup: remove if present, then unshift. Cap at the end.
|
|
141
|
+
const filtered = existing.filter((x) => x !== id);
|
|
142
|
+
filtered.unshift(id);
|
|
143
|
+
const trimmed = cap !== undefined && filtered.length > cap
|
|
144
|
+
? filtered.slice(0, cap)
|
|
145
|
+
: filtered;
|
|
146
|
+
await storage.set(key, trimmed);
|
|
147
|
+
return trimmed.length;
|
|
148
|
+
},
|
|
149
|
+
remove: async (ctx, id) => {
|
|
150
|
+
const key = buildKey(ctx, prefix);
|
|
151
|
+
const existing = (await storage.get(key)) ?? [];
|
|
152
|
+
const filtered = existing.filter((x) => x !== id);
|
|
153
|
+
if (filtered.length === existing.length)
|
|
154
|
+
return false;
|
|
155
|
+
await storage.set(key, filtered);
|
|
156
|
+
return true;
|
|
157
|
+
},
|
|
158
|
+
clear: async (ctx) => void (await storage.delete(buildKey(ctx, prefix))),
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Presence-flag store for idempotency. Each id is either claimed
|
|
163
|
+
* (storage has the key) or not (storage doesn't). The stored value is
|
|
164
|
+
* an opaque sentinel string — readers only care about presence.
|
|
165
|
+
*
|
|
166
|
+
* @example idempotent successful_payment fulfillment
|
|
167
|
+
*
|
|
168
|
+
* const idem = botSentinel(storage, 'pay:idem')
|
|
169
|
+
* if (!(await idem.claim(ctx, chargeId))) return // duplicate, no-op
|
|
170
|
+
* await fulfill(charge)
|
|
171
|
+
*/
|
|
172
|
+
export const botSentinel = (storage, prefix) => {
|
|
173
|
+
const SENTINEL = "1";
|
|
174
|
+
return {
|
|
175
|
+
keyFor: (ctx, id) => buildKey(ctx, prefix, id),
|
|
176
|
+
claim: async (ctx, id) => {
|
|
177
|
+
const key = buildKey(ctx, prefix, id);
|
|
178
|
+
const existing = await storage.get(key);
|
|
179
|
+
if (existing !== undefined)
|
|
180
|
+
return false;
|
|
181
|
+
await storage.set(key, SENTINEL);
|
|
182
|
+
return true;
|
|
183
|
+
},
|
|
184
|
+
check: async (ctx, id) => {
|
|
185
|
+
const key = buildKey(ctx, prefix, id);
|
|
186
|
+
return (await storage.get(key)) !== undefined;
|
|
187
|
+
},
|
|
188
|
+
release: async (ctx, id) => {
|
|
189
|
+
const key = buildKey(ctx, prefix, id);
|
|
190
|
+
if ((await storage.get(key)) === undefined)
|
|
191
|
+
return false;
|
|
192
|
+
await storage.delete(key);
|
|
193
|
+
return true;
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
// ─── observability hook (opt-in) ──────────────────────────────────
|
|
198
|
+
/**
|
|
199
|
+
* Wrap any `BotRecord` with trace-level logging for every read/write.
|
|
200
|
+
* Useful when debugging a specific plugin's storage flow without
|
|
201
|
+
* polluting every other plugin's logs. Defaults off.
|
|
202
|
+
*
|
|
203
|
+
* const charges = withTracing(botRecord<ChargeRecord>(...), 'pay:charge')
|
|
204
|
+
*/
|
|
205
|
+
export const withTracing = (record, label) => ({
|
|
206
|
+
keyFor: record.keyFor,
|
|
207
|
+
get: async (ctx, id) => {
|
|
208
|
+
const result = await record.get(ctx, id);
|
|
209
|
+
log.trace(`${label}.get(${id}) → ${result === undefined ? "miss" : "hit"}`);
|
|
210
|
+
return result;
|
|
211
|
+
},
|
|
212
|
+
set: async (ctx, id, value) => {
|
|
213
|
+
await record.set(ctx, id, value);
|
|
214
|
+
log.trace(`${label}.set(${id})`);
|
|
215
|
+
},
|
|
216
|
+
delete: async (ctx, id) => {
|
|
217
|
+
await record.delete(ctx, id);
|
|
218
|
+
log.trace(`${label}.delete(${id})`);
|
|
219
|
+
},
|
|
220
|
+
has: (ctx, id) => record.has(ctx, id),
|
|
221
|
+
});
|
|
222
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/bot/storage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adriangalilea/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "TypeScript utilities - logger, currency, formatter, GramIO bot plugins, and more",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
"types": "./dist/bot/access-control.d.ts",
|
|
41
41
|
"default": "./dist/bot/access-control.js"
|
|
42
42
|
},
|
|
43
|
+
"./bot/allow-list": {
|
|
44
|
+
"types": "./dist/bot/allow-list.d.ts",
|
|
45
|
+
"default": "./dist/bot/allow-list.js"
|
|
46
|
+
},
|
|
43
47
|
"./bot/coalesce": {
|
|
44
48
|
"types": "./dist/bot/coalesce.d.ts",
|
|
45
49
|
"default": "./dist/bot/coalesce.js"
|
|
@@ -59,6 +63,22 @@
|
|
|
59
63
|
"./bot/llm": {
|
|
60
64
|
"types": "./dist/bot/llm.d.ts",
|
|
61
65
|
"default": "./dist/bot/llm.js"
|
|
66
|
+
},
|
|
67
|
+
"./bot/payments": {
|
|
68
|
+
"types": "./dist/bot/payments/index.d.ts",
|
|
69
|
+
"default": "./dist/bot/payments/index.js"
|
|
70
|
+
},
|
|
71
|
+
"./bot/storage": {
|
|
72
|
+
"types": "./dist/bot/storage.d.ts",
|
|
73
|
+
"default": "./dist/bot/storage.js"
|
|
74
|
+
},
|
|
75
|
+
"./bot/ctx": {
|
|
76
|
+
"types": "./dist/bot/ctx.d.ts",
|
|
77
|
+
"default": "./dist/bot/ctx.js"
|
|
78
|
+
},
|
|
79
|
+
"./bot/callbacks": {
|
|
80
|
+
"types": "./dist/bot/callbacks.d.ts",
|
|
81
|
+
"default": "./dist/bot/callbacks.js"
|
|
62
82
|
}
|
|
63
83
|
},
|
|
64
84
|
"files": [
|
|
@@ -98,7 +118,8 @@
|
|
|
98
118
|
"gramio": "^0.10.0",
|
|
99
119
|
"marked": "^15.0.11",
|
|
100
120
|
"tsx": "^4.20.4",
|
|
101
|
-
"typescript": "^5.9.2"
|
|
121
|
+
"typescript": "^5.9.2",
|
|
122
|
+
"zod": "^4.4.3"
|
|
102
123
|
},
|
|
103
124
|
"dependencies": {
|
|
104
125
|
"chalk": "^5.6.0"
|
|
@@ -108,7 +129,8 @@
|
|
|
108
129
|
"@gramio/session": ">=0.2.0",
|
|
109
130
|
"@gramio/storage": ">=2.0.0",
|
|
110
131
|
"gramio": ">=0.10.0",
|
|
111
|
-
"marked": ">=12"
|
|
132
|
+
"marked": ">=12",
|
|
133
|
+
"zod": ">=3.22"
|
|
112
134
|
},
|
|
113
135
|
"peerDependenciesMeta": {
|
|
114
136
|
"@gramio/format": {
|
|
@@ -125,6 +147,9 @@
|
|
|
125
147
|
},
|
|
126
148
|
"marked": {
|
|
127
149
|
"optional": true
|
|
150
|
+
},
|
|
151
|
+
"zod": {
|
|
152
|
+
"optional": true
|
|
128
153
|
}
|
|
129
154
|
},
|
|
130
155
|
"publishConfig": {
|