@localhostdevs/sdk 0.13.0 → 0.15.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 +97 -29
- package/dist/argSchema.d.ts +7 -0
- package/dist/argSchema.d.ts.map +1 -0
- package/dist/argSchema.js +63 -0
- package/dist/argSchema.js.map +1 -0
- package/dist/bot.d.ts +16 -15
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +217 -87
- package/dist/bot.js.map +1 -1
- package/dist/collect.d.ts +46 -0
- package/dist/collect.d.ts.map +1 -0
- package/dist/collect.js +68 -0
- package/dist/collect.js.map +1 -0
- package/dist/collectStore.d.ts +31 -0
- package/dist/collectStore.d.ts.map +1 -0
- package/dist/collectStore.js +96 -0
- package/dist/collectStore.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jsonSchema.d.ts +5 -0
- package/dist/jsonSchema.d.ts.map +1 -0
- package/dist/jsonSchema.js +7 -0
- package/dist/jsonSchema.js.map +1 -0
- package/dist/transport.d.ts +15 -4
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +5 -0
- package/dist/transport.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +133 -50
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +64 -61
package/README.md
CHANGED
|
@@ -22,11 +22,11 @@ const bot = new Bot({
|
|
|
22
22
|
// apiKey: process.env.BOT_SECRET, // optional; auto-read from env if unset
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
bot.cmd('ping', async (ctx) => {
|
|
25
|
+
bot.cmd({ name: 'ping' }, async (ctx) => {
|
|
26
26
|
await ctx.reply({ text: 'pong' });
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
bot.cmd('echo', async (ctx) => {
|
|
29
|
+
bot.cmd({ name: 'echo' }, async (ctx) => {
|
|
30
30
|
await ctx.reply({ text: `echo: ${JSON.stringify(ctx.args)}` });
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -53,15 +53,63 @@ The bot stays online for as long as the process runs. The gateway keeps the conn
|
|
|
53
53
|
| `serverUrl` | `string` | `wss://bot-api.localhostdevs.com/bot` (override with `LHD_SERVER_URL`) | Production gateway is baked in — most users leave this alone. Only override for local dev or self-hosted gateways. |
|
|
54
54
|
| `idempotencyLruSize` | `number` | `1024` | How many recent message IDs to remember for deduplication. |
|
|
55
55
|
|
|
56
|
-
### `bot.cmd(
|
|
56
|
+
### `bot.cmd(def, handler)`
|
|
57
57
|
|
|
58
|
-
Register a handler for a command. Must be called before `connect()`.
|
|
58
|
+
Register a handler for a command. Must be called before `connect()`. The first argument is a **command definition object** with the following fields:
|
|
59
|
+
|
|
60
|
+
| Field | Type | Notes |
|
|
61
|
+
| ------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| `name` | `string` (required) | Command name consumers dispatch (e.g. `'ping'`, `'topic'`). |
|
|
63
|
+
| `description` | `string` | Human-readable description shown on the marketplace/workflow picker. |
|
|
64
|
+
| `args` | `Record<string, ArgSpec>` | Declare the expected arguments (see below). **Advertise-only** by default — fills the marketplace and workflow picker but does NOT validate at runtime unless `validate: true`. |
|
|
65
|
+
| `returns` | `{ kind: ReplyKind, data?: Record<string, 'string' \| 'number' \| 'boolean'> }` | Declare the reply kind. Enforced: the handler must call the matching reply method or the SDK throws (see Reply-kind enforcement below). |
|
|
66
|
+
| `validate` | `boolean` | When `true`, the SDK validates `ctx.args` against the declared `args` before running your handler. A bad dispatch is rejected with a structured `invalid_args` error. Also narrows TypeScript types: `required` fields become typed-present in `ctx.args`. Without `validate`, all arg fields are typed optional. |
|
|
67
|
+
| `streaming` | `boolean` | Override the bot-level streaming flag for this command only. |
|
|
68
|
+
| `mimeType` | `string` | MIME-type hint advertised in IDENTIFY (advertising-only, doesn't affect runtime). |
|
|
69
|
+
|
|
70
|
+
#### `ArgSpec` shape
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
interface ArgSpec {
|
|
74
|
+
type: 'string' | 'number' | 'boolean' | 'enum';
|
|
75
|
+
required?: boolean;
|
|
76
|
+
description?: string;
|
|
77
|
+
values?: readonly string[]; // required when type === 'enum'
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### `returns.kind` vocabulary
|
|
82
|
+
|
|
83
|
+
`'text'` | `'list'` | `'table'` | `'image'` | `'buttons'` | `'collect'`
|
|
84
|
+
|
|
85
|
+
The declared kind is **enforced at runtime**: if the handler calls a reply method that doesn't match the declaration (e.g. `returns: { kind: 'list' }` but the handler calls `ctx.reply()`), the SDK throws a hard error. TypeScript also narrows `ctx`'s available reply methods to just the ones valid for the declared kind.
|
|
86
|
+
|
|
87
|
+
#### Example
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
bot.cmd({
|
|
91
|
+
name: 'topic',
|
|
92
|
+
description: 'Scrape trends for a query, then pick one',
|
|
93
|
+
args: {
|
|
94
|
+
query: { type: 'string', required: true, description: 'Search query' },
|
|
95
|
+
format: { type: 'string', description: 'e.g. short_30s' },
|
|
96
|
+
voice: { type: 'enum', values: ['on', 'off'] },
|
|
97
|
+
},
|
|
98
|
+
returns: { kind: 'list', data: { jobId: 'string', state: 'string' } },
|
|
99
|
+
validate: false, // opt-in: when true, args are validated AND required fields typed-present
|
|
100
|
+
}, async (ctx) => {
|
|
101
|
+
// ctx.args is typed from `args`; ctx reply methods are narrowed to returns.kind
|
|
102
|
+
await ctx.replyList([{ title: ctx.args.query ?? '' }]);
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Handler receives a `CommandContext`:
|
|
59
107
|
|
|
60
108
|
```ts
|
|
61
|
-
bot.cmd('greet', async (ctx) => {
|
|
62
|
-
// ctx.args:
|
|
109
|
+
bot.cmd({ name: 'greet' }, async (ctx) => {
|
|
110
|
+
// ctx.args: parsed args from the consumer
|
|
63
111
|
// ctx.command: 'greet'
|
|
64
|
-
// ctx.msgId:
|
|
112
|
+
// ctx.msgId: unique id for this invocation
|
|
65
113
|
|
|
66
114
|
await ctx.reply({ text: `Hello, ${ctx.args.name ?? 'world'}!` });
|
|
67
115
|
|
|
@@ -92,7 +140,7 @@ The gateway pings the bot every 30 seconds and the SDK responds. If the gateway
|
|
|
92
140
|
A reply can carry a `dispatch` directive to chain a command to another bot:
|
|
93
141
|
|
|
94
142
|
```js
|
|
95
|
-
bot.cmd('summary', async (ctx) => {
|
|
143
|
+
bot.cmd({ name: 'summary' }, async (ctx) => {
|
|
96
144
|
await ctx.reply({
|
|
97
145
|
text: 'fetching price first…',
|
|
98
146
|
dispatch: { to: 'price-bot', command: 'price', args: { ticker: 'AAPL' } },
|
|
@@ -107,11 +155,14 @@ Chains run up to depth 5 with loop detection. The original consumer pays for eve
|
|
|
107
155
|
By default `ctx.reply({ text })` sends a plain-text body — the consumer
|
|
108
156
|
renders it as text. To get richer rendering (source-badge lists, striped
|
|
109
157
|
tables) on the dashboard Test Console and the public Try widget, return a
|
|
110
|
-
**kinded** body via the
|
|
158
|
+
**kinded** body via the helpers:
|
|
111
159
|
|
|
112
160
|
```js
|
|
113
161
|
// List output
|
|
114
|
-
bot.cmd(
|
|
162
|
+
bot.cmd({
|
|
163
|
+
name: 'headlines',
|
|
164
|
+
returns: { kind: 'list' },
|
|
165
|
+
}, async (ctx) => {
|
|
115
166
|
await ctx.replyList(
|
|
116
167
|
[
|
|
117
168
|
{ label: 'AP', title: 'Story one', secondary: '2m', href: '…' },
|
|
@@ -122,7 +173,10 @@ bot.cmd('headlines', async (ctx) => {
|
|
|
122
173
|
});
|
|
123
174
|
|
|
124
175
|
// Table output
|
|
125
|
-
bot.cmd(
|
|
176
|
+
bot.cmd({
|
|
177
|
+
name: 'top5',
|
|
178
|
+
returns: { kind: 'table' },
|
|
179
|
+
}, async (ctx) => {
|
|
126
180
|
await ctx.replyTable({
|
|
127
181
|
headers: ['ticker', 'price', 'change'],
|
|
128
182
|
rows: [
|
|
@@ -159,10 +213,11 @@ guard flips, so if you catch the error you can still send a corrected
|
|
|
159
213
|
further reply calls throw — the SDK guarantees exactly-one reply per
|
|
160
214
|
command.
|
|
161
215
|
|
|
162
|
-
**
|
|
163
|
-
|
|
164
|
-
(`
|
|
165
|
-
|
|
216
|
+
**Reply-kind enforcement.** When `returns.kind` is declared on the command
|
|
217
|
+
definition, the SDK enforces it at runtime: calling a mismatched reply
|
|
218
|
+
method (e.g. `ctx.reply()` when `returns: { kind: 'list' }`) throws a hard
|
|
219
|
+
error. TypeScript also narrows `ctx`'s available reply methods to the ones
|
|
220
|
+
valid for the declared kind, so mismatches are caught at compile time.
|
|
166
221
|
|
|
167
222
|
## Streaming progress (`ctx.update`)
|
|
168
223
|
|
|
@@ -175,7 +230,7 @@ const bot = new Bot({
|
|
|
175
230
|
streaming: true, // enables ctx.update across all commands
|
|
176
231
|
});
|
|
177
232
|
|
|
178
|
-
bot.cmd('analyze', async (ctx) => {
|
|
233
|
+
bot.cmd({ name: 'analyze' }, async (ctx) => {
|
|
179
234
|
await ctx.update({ progress: 10, text: 'Fetching…' });
|
|
180
235
|
await ctx.update({ progress: 60, text: 'Crunching…' });
|
|
181
236
|
await ctx.reply({
|
|
@@ -186,11 +241,11 @@ bot.cmd('analyze', async (ctx) => {
|
|
|
186
241
|
});
|
|
187
242
|
```
|
|
188
243
|
|
|
189
|
-
Or per-command:
|
|
244
|
+
Or per-command using `streaming` in the definition:
|
|
190
245
|
|
|
191
246
|
```js
|
|
192
|
-
bot.cmd('analyze',
|
|
193
|
-
bot.cmd('ping', async (ctx) => { /* no ctx.update here */ });
|
|
247
|
+
bot.cmd({ name: 'analyze', streaming: true }, async (ctx) => { /* … */ });
|
|
248
|
+
bot.cmd({ name: 'ping' }, async (ctx) => { /* no ctx.update here */ });
|
|
194
249
|
```
|
|
195
250
|
|
|
196
251
|
**Progress shapes** (use whichever fits the work):
|
|
@@ -218,15 +273,15 @@ Tell the platform what each command's reply looks like so the bot
|
|
|
218
273
|
detail page can show consumers what to expect:
|
|
219
274
|
|
|
220
275
|
```js
|
|
221
|
-
bot.cmd('chart',
|
|
276
|
+
bot.cmd({ name: 'chart', streaming: true, mimeType: 'image/png' }, async (ctx) => {
|
|
222
277
|
await ctx.reply({ data: chartBytes, mimeType: 'image/png' });
|
|
223
278
|
});
|
|
224
279
|
|
|
225
|
-
bot.cmd('summarize',
|
|
280
|
+
bot.cmd({ name: 'summarize', mimeType: 'text/markdown' }, async (ctx) => {
|
|
226
281
|
await ctx.reply({ text: '# Summary\n…', mimeType: 'text/markdown' });
|
|
227
282
|
});
|
|
228
283
|
|
|
229
|
-
bot.cmd('ping', async (ctx) => { // no
|
|
284
|
+
bot.cmd({ name: 'ping' }, async (ctx) => { // no mimeType — displays as text/plain
|
|
230
285
|
await ctx.reply({ text: 'pong' });
|
|
231
286
|
});
|
|
232
287
|
```
|
|
@@ -267,8 +322,7 @@ v0.4 is additive — nothing breaks for bots calling only `ctx.reply()`.
|
|
|
267
322
|
New surface:
|
|
268
323
|
|
|
269
324
|
- `new Bot({ …, streaming: true })` to enable `ctx.update()`
|
|
270
|
-
- `
|
|
271
|
-
command without touching bot-init
|
|
325
|
+
- `streaming: true` inside the command definition to flip the flag per command
|
|
272
326
|
- `ctx.update({ progress?, text?, data?, mimeType? })` — send 1+
|
|
273
327
|
intermediate frames before `ctx.reply()`
|
|
274
328
|
- `mimeType` on `ctx.reply()` for the existing final-reply path
|
|
@@ -277,11 +331,25 @@ No env-var changes, no protocol breakage, no upstream re-auth.
|
|
|
277
331
|
|
|
278
332
|
## v0.4.0 → v0.4.1 (per-command mimeType)
|
|
279
333
|
|
|
280
|
-
Additive — no breaking changes. The `mimeType?` field in
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
334
|
+
Additive — no breaking changes. The `mimeType?` field in the command definition
|
|
335
|
+
is optional; bots that ignore it work exactly the same. The SDK auto-builds an
|
|
336
|
+
IDENTIFY-time `commands` array from your registered handlers so the platform can
|
|
337
|
+
display them on the bot detail page.
|
|
338
|
+
|
|
339
|
+
## v0.14 → v0.15 (object `cmd()`)
|
|
340
|
+
|
|
341
|
+
**Breaking.** See [MIGRATION.md](./MIGRATION.md) for the full guide.
|
|
342
|
+
|
|
343
|
+
`cmd()` now takes a **command definition object** as its first argument. The
|
|
344
|
+
string-form is removed.
|
|
345
|
+
|
|
346
|
+
```diff
|
|
347
|
+
- bot.cmd("ping", async (ctx) => { … })
|
|
348
|
+
+ bot.cmd({ name: "ping" }, async (ctx) => { … })
|
|
349
|
+
|
|
350
|
+
- bot.cmd("analyze", { streaming: true }, async (ctx) => { … })
|
|
351
|
+
+ bot.cmd({ name: "analyze", streaming: true }, async (ctx) => { … })
|
|
352
|
+
```
|
|
285
353
|
|
|
286
354
|
## License
|
|
287
355
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ZodType } from 'zod';
|
|
2
|
+
import type { ArgSpec, ReturnsSpec } from './types.js';
|
|
3
|
+
export declare function argsToJsonSchema(args: Record<string, ArgSpec>): Record<string, unknown>;
|
|
4
|
+
export declare function returnsDataToJsonSchema(data: ReturnsSpec['data']): Record<string, unknown> | undefined;
|
|
5
|
+
export declare function returnsDataToZod(data: ReturnsSpec['data']): ZodType | undefined;
|
|
6
|
+
export declare function argsToZod(args: Record<string, ArgSpec>): ZodType;
|
|
7
|
+
//# sourceMappingURL=argSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argSchema.d.ts","sourceRoot":"","sources":["../src/argSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAavD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUvF;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKrC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,SAAS,CAO/E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAkBhE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
function propSchema(s) {
|
|
3
|
+
if (s.type === 'enum') {
|
|
4
|
+
const p = { type: 'string', enum: [...(s.values ?? [])] };
|
|
5
|
+
if (s.description)
|
|
6
|
+
p.description = s.description;
|
|
7
|
+
return p;
|
|
8
|
+
}
|
|
9
|
+
const p = { type: s.type };
|
|
10
|
+
if (s.description)
|
|
11
|
+
p.description = s.description;
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
14
|
+
export function argsToJsonSchema(args) {
|
|
15
|
+
const properties = {};
|
|
16
|
+
const required = [];
|
|
17
|
+
for (const [name, spec] of Object.entries(args)) {
|
|
18
|
+
properties[name] = propSchema(spec);
|
|
19
|
+
if (spec.required)
|
|
20
|
+
required.push(name);
|
|
21
|
+
}
|
|
22
|
+
const out = { type: 'object', properties };
|
|
23
|
+
if (required.length)
|
|
24
|
+
out.required = required;
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
export function returnsDataToJsonSchema(data) {
|
|
28
|
+
if (!data)
|
|
29
|
+
return undefined;
|
|
30
|
+
const properties = {};
|
|
31
|
+
for (const [name, t] of Object.entries(data))
|
|
32
|
+
properties[name] = { type: t };
|
|
33
|
+
return { type: 'object', properties };
|
|
34
|
+
}
|
|
35
|
+
export function returnsDataToZod(data) {
|
|
36
|
+
if (!data)
|
|
37
|
+
return undefined;
|
|
38
|
+
const shape = {};
|
|
39
|
+
for (const [name, t] of Object.entries(data)) {
|
|
40
|
+
shape[name] = t === 'number' ? z.number() : t === 'boolean' ? z.boolean() : z.string();
|
|
41
|
+
}
|
|
42
|
+
return z.object(shape);
|
|
43
|
+
}
|
|
44
|
+
export function argsToZod(args) {
|
|
45
|
+
const shape = {};
|
|
46
|
+
for (const [name, spec] of Object.entries(args)) {
|
|
47
|
+
if (spec.type === 'enum' && (!spec.values || spec.values.length === 0)) {
|
|
48
|
+
throw new Error(`enum arg requires a non-empty \`values\` array`);
|
|
49
|
+
}
|
|
50
|
+
let field = spec.type === 'string'
|
|
51
|
+
? z.string()
|
|
52
|
+
: spec.type === 'number'
|
|
53
|
+
? z.number()
|
|
54
|
+
: spec.type === 'boolean'
|
|
55
|
+
? z.boolean()
|
|
56
|
+
: z.enum([...(spec.values ?? [])]);
|
|
57
|
+
if (!spec.required)
|
|
58
|
+
field = field.optional();
|
|
59
|
+
shape[name] = field;
|
|
60
|
+
}
|
|
61
|
+
return z.object(shape);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=argSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argSchema.js","sourceRoot":"","sources":["../src/argSchema.ts"],"names":[],"mappings":"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"}
|
package/dist/bot.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid';
|
|
2
|
-
import type { BotOptions, CommandHandler,
|
|
2
|
+
import type { ArgsOf, BotOptions, CommandContext, CommandDef, CommandHandler, ReturnsOf } from './types.js';
|
|
3
3
|
export { SDK_PACKAGE_VERSION } from './version.js';
|
|
4
4
|
export declare class Bot {
|
|
5
5
|
private readonly opts;
|
|
@@ -10,18 +10,18 @@ export declare class Bot {
|
|
|
10
10
|
private readonly cmdOpts;
|
|
11
11
|
private readonly seen;
|
|
12
12
|
private readonly seenQueue;
|
|
13
|
-
private readonly
|
|
14
|
-
private
|
|
15
|
-
private
|
|
13
|
+
private readonly collectOpts;
|
|
14
|
+
private collectStore;
|
|
15
|
+
private collectTimer;
|
|
16
16
|
private closing;
|
|
17
17
|
private reconnectTimer;
|
|
18
18
|
private reconnectAttempt;
|
|
19
19
|
private cachedApiKey;
|
|
20
20
|
constructor(opts: BotOptions);
|
|
21
|
-
/** Register a
|
|
22
|
-
cmd(
|
|
23
|
-
/**
|
|
24
|
-
|
|
21
|
+
/** Register a command from its definition object. The ONLY public way to add a command. */
|
|
22
|
+
cmd<const D extends CommandDef>(def: D, handler: (ctx: CommandContext<ArgsOf<D>, ReturnsOf<D>>) => void | Promise<void>): this;
|
|
23
|
+
/** Internal: the single registration path. Not part of the public API. */
|
|
24
|
+
private registerHandler;
|
|
25
25
|
/** Register an internal action handler (Interactive Prompts). Stored in the
|
|
26
26
|
* same handler map `cmd()` uses — so dispatch routing is unchanged — but
|
|
27
27
|
* flagged `internal: true` so it is EXCLUDED from the IDENTIFY advertised
|
|
@@ -49,13 +49,14 @@ export declare class Bot {
|
|
|
49
49
|
* Users can override by calling cmd('commands', ...) themselves. */
|
|
50
50
|
private replyWithCommandList;
|
|
51
51
|
private dispatch;
|
|
52
|
-
private
|
|
53
|
-
/** Lazily open the
|
|
54
|
-
private
|
|
55
|
-
/** The sink invoked when a
|
|
56
|
-
* not throw — a throwing sink leaves the
|
|
57
|
-
|
|
58
|
-
private
|
|
52
|
+
private resolveCollectDbPath;
|
|
53
|
+
/** Lazily open the collect store (node:sqlite) and start the close loop. */
|
|
54
|
+
private ensureCollectStore;
|
|
55
|
+
/** The sink invoked when a collect closes: user callback if set, else push a
|
|
56
|
+
* frame / log. Must not throw — a throwing sink leaves the collect open for
|
|
57
|
+
* retry. */
|
|
58
|
+
private collectSink;
|
|
59
|
+
private startCollectLoop;
|
|
59
60
|
private makeContext;
|
|
60
61
|
private isDuplicate;
|
|
61
62
|
private recordSeen;
|
package/dist/bot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAWhC,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EAGV,cAAc,EACd,UAAU,EACV,cAAc,EAMd,SAAS,EAGV,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AA8CnD,qBAAa,GAAG;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAG1B;IACF,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,IAAI,EAAE,UAAU;IA2C5B,2FAA2F;IAC3F,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,EAC5B,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC9E,IAAI;IAgCP,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IASvB;;;;wEAIoE;IACpE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAIjD,OAAO,CAAC,cAAc;IAMtB,2FAA2F;IACrF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,iFAAiF;YACnE,aAAa;IAiE3B,OAAO,CAAC,iBAAiB;YAcX,YAAY;IAe1B;;;;;OAKG;YACW,aAAa;IAoB3B,0DAA0D;IACpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;yEAEqE;IACrE,OAAO,CAAC,oBAAoB;YAYd,QAAQ;IAgGtB,OAAO,CAAC,oBAAoB;IAQ5B,4EAA4E;IAC5E,OAAO,CAAC,kBAAkB;IAc1B;;iBAEa;IACb,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,WAAW;IA2WnB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;CAQnB;AAGD,OAAO,EAAE,MAAM,EAAE,CAAC"}
|