aurival 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 +202 -0
- package/README.md +195 -0
- package/dist/auth.d.ts +67 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +416 -0
- package/dist/auth.js.map +1 -0
- package/dist/bot.d.ts +76 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +278 -0
- package/dist/bot.js.map +1 -0
- package/dist/cli.d.ts +27 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +137 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +140 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +205 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +77 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +106 -0
- package/dist/events.js.map +1 -0
- package/dist/http.d.ts +48 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +201 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/socket.d.ts +61 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +447 -0
- package/dist/socket.js.map +1 -0
- package/package.json +59 -0
package/dist/bot.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/** The developer-facing surface: declare commands, call run(), we hold the socket. */
|
|
2
|
+
import { Auth, KeyFile, machineLabel, pair, resolveHost } from './auth.js';
|
|
3
|
+
import { AurivalError, RateLimitError } from './errors.js';
|
|
4
|
+
import { Context, Event } from './events.js';
|
|
5
|
+
import { DEFAULT_HOST, HttpClient, defaultLogger } from './http.js';
|
|
6
|
+
import { Socket } from './socket.js';
|
|
7
|
+
/** How long a clean shutdown waits for handlers that are still running (SDK-32). */
|
|
8
|
+
export const SHUTDOWN_GRACE_MS = 10_000;
|
|
9
|
+
// Mirrors the server's own normalisation (commands.go) so `Ping` finds the
|
|
10
|
+
// handler for the `ping` that comes back on the wire. Not validation.
|
|
11
|
+
function lookupKey(name) {
|
|
12
|
+
return name.trim().toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Load the key file, or pair this machine and save one.
|
|
16
|
+
*
|
|
17
|
+
* `Bot.start` and `aurival init` both come through here, so the code and the
|
|
18
|
+
* fingerprint print identically either way (SDK-43) — the printout is the thing
|
|
19
|
+
* a developer compares in the app, and two spellings of it would drift.
|
|
20
|
+
*/
|
|
21
|
+
export async function ensurePaired(http, keyFile, host, log, signal) {
|
|
22
|
+
const loaded = await keyFile.load();
|
|
23
|
+
if (loaded !== null)
|
|
24
|
+
return { ...loaded, paired: false };
|
|
25
|
+
const { key, machine } = await pair(http, {
|
|
26
|
+
machineLabel: machineLabel(),
|
|
27
|
+
host,
|
|
28
|
+
out: (line) => process.stdout.write(line + '\n'),
|
|
29
|
+
logger: log,
|
|
30
|
+
signal,
|
|
31
|
+
});
|
|
32
|
+
await keyFile.save(key, machine);
|
|
33
|
+
return { key, machine, paired: true };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The one door to command sync, so the lane that syncs is always the lane that
|
|
37
|
+
* reports. Both `Bot` call sites go through here.
|
|
38
|
+
*
|
|
39
|
+
* Exported for the tests, not from `index.ts` — the package's export list
|
|
40
|
+
* mirrors Python's `__all__` (SDK-7) and this is not on it.
|
|
41
|
+
*/
|
|
42
|
+
export async function syncCommandsAndReport(http, bot, payload, log) {
|
|
43
|
+
reportConflicts(await http.syncCommands(bot, payload), log);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One warning line per shadowed chat (S11). Silently dropping `conflicts` is
|
|
47
|
+
* the silence the field exists to end: the developer whose command never fires.
|
|
48
|
+
*
|
|
49
|
+
* The wire carries chat references and deliberately not the other bot
|
|
50
|
+
* (server.go's handleReplaceCommands), so the chat id is all a line can name.
|
|
51
|
+
*/
|
|
52
|
+
export function reportConflicts(response, log) {
|
|
53
|
+
const rows = response['data'];
|
|
54
|
+
if (!Array.isArray(rows))
|
|
55
|
+
return;
|
|
56
|
+
for (const row of rows) {
|
|
57
|
+
if (typeof row !== 'object' || row === null)
|
|
58
|
+
continue;
|
|
59
|
+
const record = row;
|
|
60
|
+
const name = typeof record['name'] === 'string' ? record['name'] : '';
|
|
61
|
+
const conflicts = record['conflicts'];
|
|
62
|
+
if (!Array.isArray(conflicts))
|
|
63
|
+
continue;
|
|
64
|
+
for (const chat of conflicts) {
|
|
65
|
+
if (typeof chat !== 'string' || chat === '')
|
|
66
|
+
continue;
|
|
67
|
+
log.warn(`/${name} is shadowed by another bot in ${chat}, so it will not reach you there`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A bot. Register commands, then `run()`.
|
|
73
|
+
*
|
|
74
|
+
* First run pairs this machine: it prints a code, you approve it in the app, and
|
|
75
|
+
* the key lands in ./.aurival/. Every later run just starts.
|
|
76
|
+
*/
|
|
77
|
+
export class Bot {
|
|
78
|
+
#registered = new Map();
|
|
79
|
+
#inflight = new Set();
|
|
80
|
+
#log;
|
|
81
|
+
#host;
|
|
82
|
+
#keyPath;
|
|
83
|
+
#errorHook = null;
|
|
84
|
+
#http = null;
|
|
85
|
+
constructor(options = {}) {
|
|
86
|
+
this.#log = options.logger ?? defaultLogger();
|
|
87
|
+
this.#host = options.host;
|
|
88
|
+
this.#keyPath = options.keyPath;
|
|
89
|
+
}
|
|
90
|
+
command(name, second, third) {
|
|
91
|
+
const description = typeof second === 'string' ? second : '';
|
|
92
|
+
const handler = typeof second === 'string' ? third : second;
|
|
93
|
+
if (handler === undefined)
|
|
94
|
+
throw new AurivalError(`command(${name}) needs a handler`);
|
|
95
|
+
this.#registered.set(lookupKey(name), { command: { name, description }, handler });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Called with (error, context | null) for anything the SDK caught for you: a
|
|
99
|
+
* handler that threw, a `problem` frame, a backlog overflow.
|
|
100
|
+
*/
|
|
101
|
+
onError(fn) {
|
|
102
|
+
this.#errorHook = fn;
|
|
103
|
+
}
|
|
104
|
+
// -- running -----------------------------------------------------------
|
|
105
|
+
/** Installs signal handlers and runs until SIGINT/SIGTERM or something fatal. */
|
|
106
|
+
async run() {
|
|
107
|
+
const controller = new AbortController();
|
|
108
|
+
const stop = () => controller.abort();
|
|
109
|
+
process.on('SIGINT', stop);
|
|
110
|
+
process.on('SIGTERM', stop);
|
|
111
|
+
try {
|
|
112
|
+
await this.start(controller.signal);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
process.off('SIGINT', stop);
|
|
116
|
+
process.off('SIGTERM', stop);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async start(signal) {
|
|
120
|
+
const host = this.#host ?? resolveHost();
|
|
121
|
+
if (host !== DEFAULT_HOST) {
|
|
122
|
+
// Printed, not logged: a redirected host is the first thing to check when
|
|
123
|
+
// nothing works, and a logger set to WARNING would hide it.
|
|
124
|
+
process.stdout.write(`aurival: using ${host}\n`);
|
|
125
|
+
}
|
|
126
|
+
const abort = signal ?? new AbortController().signal;
|
|
127
|
+
const unauth = new HttpClient(host, null, this.#log);
|
|
128
|
+
const keyFile = new KeyFile(this.#keyPath ?? null);
|
|
129
|
+
const { key, machine } = await ensurePaired(unauth, keyFile, host, this.#log, abort);
|
|
130
|
+
// The key file's own path, so a `key_revoked` says which file to remove
|
|
131
|
+
// (S7) — including when AURIVAL_KEY_PATH put it somewhere unexpected.
|
|
132
|
+
const auth = new Auth(unauth, key, machine, this.#log, keyFile.path);
|
|
133
|
+
const http = new HttpClient(host, auth, this.#log);
|
|
134
|
+
this.#http = http;
|
|
135
|
+
const syncRetry = await this.#syncCommands(http, machine.bot, abort);
|
|
136
|
+
const socket = new Socket(http, auth, {
|
|
137
|
+
dispatch: (event) => this.#dispatch(event),
|
|
138
|
+
onProblem: (problem) => {
|
|
139
|
+
void this.#callErrorHook(problem, null);
|
|
140
|
+
},
|
|
141
|
+
logger: this.#log,
|
|
142
|
+
});
|
|
143
|
+
try {
|
|
144
|
+
await socket.run(abort);
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
syncRetry?.cancel();
|
|
148
|
+
await this.#drainHandlers();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** A bounded wait, then go anyway. A clean close earns no `bye`, correctly. */
|
|
152
|
+
async #drainHandlers() {
|
|
153
|
+
if (this.#inflight.size === 0)
|
|
154
|
+
return;
|
|
155
|
+
await Promise.race([
|
|
156
|
+
Promise.allSettled([...this.#inflight]),
|
|
157
|
+
new Promise((resolve) => setTimeout(resolve, SHUTDOWN_GRACE_MS)),
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
// -- command sync ------------------------------------------------------
|
|
161
|
+
/**
|
|
162
|
+
* Sync on every run. A rate limit does NOT take the bot offline (SDK-35):
|
|
163
|
+
* command rows are durable, so we connect with whatever the server already has
|
|
164
|
+
* and land the sync in the background.
|
|
165
|
+
*/
|
|
166
|
+
async #syncCommands(http, bot, signal) {
|
|
167
|
+
const payload = [...this.#registered.values()].map((r) => ({
|
|
168
|
+
name: r.command.name,
|
|
169
|
+
description: r.command.description,
|
|
170
|
+
}));
|
|
171
|
+
try {
|
|
172
|
+
await syncCommandsAndReport(http, bot, payload, this.#log);
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
catch (exc) {
|
|
176
|
+
if (!(exc instanceof RateLimitError))
|
|
177
|
+
throw exc;
|
|
178
|
+
this.#log.warn(`command sync is rate limited (${exc.code}); connecting with the server's ` +
|
|
179
|
+
`current set and retrying in the background`);
|
|
180
|
+
const controller = new AbortController();
|
|
181
|
+
void this.#retrySync(http, bot, payload, exc, controller.signal, signal);
|
|
182
|
+
return { cancel: () => controller.abort() };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async #retrySync(http, bot, payload, first, cancelled, stopping) {
|
|
186
|
+
let delayMs = (first.retry_after ?? 60) * 1000;
|
|
187
|
+
for (;;) {
|
|
188
|
+
if (await sleepUntilAborted(delayMs, cancelled, stopping))
|
|
189
|
+
return;
|
|
190
|
+
try {
|
|
191
|
+
// The background lane reports conflicts too: a bot whose first sync was
|
|
192
|
+
// rate limited must not be the one bot that never hears about them.
|
|
193
|
+
await syncCommandsAndReport(http, bot, payload, this.#log);
|
|
194
|
+
}
|
|
195
|
+
catch (exc) {
|
|
196
|
+
if (exc instanceof RateLimitError) {
|
|
197
|
+
delayMs = (exc.retry_after ?? 60) * 1000;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (exc instanceof AurivalError) {
|
|
201
|
+
this.#log.error(`command sync failed: ${exc.message}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
throw exc;
|
|
205
|
+
}
|
|
206
|
+
process.stdout.write('aurival: command sync landed\n');
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// -- dispatch ----------------------------------------------------------
|
|
211
|
+
async #dispatch(event) {
|
|
212
|
+
const work = this.#handle(event);
|
|
213
|
+
this.#inflight.add(work);
|
|
214
|
+
try {
|
|
215
|
+
await work;
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
this.#inflight.delete(work);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* One event. Runs the handler, never lets it take the bot down (SDK-16).
|
|
223
|
+
*
|
|
224
|
+
* Note what is NOT in this frame: no key, no seed, no token.
|
|
225
|
+
*/
|
|
226
|
+
async #handle(event) {
|
|
227
|
+
if (event.type !== 'command.invoked')
|
|
228
|
+
return;
|
|
229
|
+
const name = typeof event.data['command'] === 'string' ? event.data['command'] : '';
|
|
230
|
+
const registered = this.#registered.get(lookupKey(name));
|
|
231
|
+
if (registered === undefined) {
|
|
232
|
+
// The server routes by its own declared set, so this is a stale sync or a
|
|
233
|
+
// name we just removed. Not an error.
|
|
234
|
+
this.#log.debug(`no handler for command ${JSON.stringify(name)}`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (this.#http === null)
|
|
238
|
+
return;
|
|
239
|
+
const ctx = Context.fromEvent(event, this.#http);
|
|
240
|
+
try {
|
|
241
|
+
await registered.handler(ctx);
|
|
242
|
+
}
|
|
243
|
+
catch (exc) {
|
|
244
|
+
// One bad command must not take the bot offline (SDK-16).
|
|
245
|
+
this.#log.error(`handler for ${JSON.stringify(name)} threw: ${exc instanceof Error ? (exc.stack ?? exc.message) : String(exc)}`);
|
|
246
|
+
await this.#callErrorHook(exc, ctx);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async #callErrorHook(error, ctx) {
|
|
250
|
+
if (this.#errorHook === null)
|
|
251
|
+
return;
|
|
252
|
+
try {
|
|
253
|
+
await this.#errorHook(error, ctx);
|
|
254
|
+
}
|
|
255
|
+
catch (exc) {
|
|
256
|
+
// An error hook that throws is not an outage either.
|
|
257
|
+
this.#log.error(`error hook threw: ${exc instanceof Error ? exc.message : String(exc)}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** Resolves true if either signal fired first — a wait must never outlive a SIGINT. */
|
|
262
|
+
function sleepUntilAborted(ms, a, b) {
|
|
263
|
+
if (a.aborted || b.aborted)
|
|
264
|
+
return Promise.resolve(true);
|
|
265
|
+
return new Promise((resolve) => {
|
|
266
|
+
const done = (value) => {
|
|
267
|
+
clearTimeout(timer);
|
|
268
|
+
a.removeEventListener('abort', onAbort);
|
|
269
|
+
b.removeEventListener('abort', onAbort);
|
|
270
|
+
resolve(value);
|
|
271
|
+
};
|
|
272
|
+
const onAbort = () => done(true);
|
|
273
|
+
const timer = setTimeout(() => done(false), ms);
|
|
274
|
+
a.addEventListener('abort', onAbort, { once: true });
|
|
275
|
+
b.addEventListener('abort', onAbort, { once: true });
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=bot.js.map
|
package/dist/bot.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `aurival init` (SDK-43): from an empty folder to a running bot in one command.
|
|
4
|
+
*
|
|
5
|
+
* One subcommand and `--help`, nothing else. The pairing printout is `run()`'s
|
|
6
|
+
* own, through `ensurePaired`, so the code and fingerprint a developer compares
|
|
7
|
+
* in the app are the same lines either way.
|
|
8
|
+
*/
|
|
9
|
+
export declare const USAGE = "aurival \u2014 write a bot for Aurival\n\nusage:\n aurival init pair this machine and write a starter bot in this folder\n aurival --help this\n\ninit writes bot.ts when the folder already has TypeScript (a tsconfig.json),\nand bot.js otherwise, so the file it names is one you can actually run. It\nnever overwrites an existing bot file.\n";
|
|
10
|
+
/**
|
|
11
|
+
* The one rule, stated so it can be applied: TypeScript if the folder already
|
|
12
|
+
* has a tsconfig.json, plain JS otherwise. A folder with no TS toolchain gets a
|
|
13
|
+
* file `node` runs as it stands — a `bot.ts` there would be a scaffold whose
|
|
14
|
+
* printed next step does not work.
|
|
15
|
+
*/
|
|
16
|
+
export declare function starterFilename(dir: string): 'bot.ts' | 'bot.js';
|
|
17
|
+
/** The README's bot, verbatim in behaviour: declare /ping, answer pong. */
|
|
18
|
+
export declare function starterSource(filename: string): string;
|
|
19
|
+
export interface CliIO {
|
|
20
|
+
cwd: string;
|
|
21
|
+
out: (line: string) => void;
|
|
22
|
+
err: (line: string) => void;
|
|
23
|
+
}
|
|
24
|
+
/** Returns the process exit code. Never calls `process.exit` itself. */
|
|
25
|
+
export declare function main(argv: string[], io?: CliIO): Promise<number>;
|
|
26
|
+
export declare function init(io: CliIO): Promise<number>;
|
|
27
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAUH,eAAO,MAAM,KAAK,iWASjB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAEhE;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAetD;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAUD,wEAAwE;AACxE,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnF;AAED,wBAAsB,IAAI,CAAC,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CrD"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `aurival init` (SDK-43): from an empty folder to a running bot in one command.
|
|
4
|
+
*
|
|
5
|
+
* One subcommand and `--help`, nothing else. The pairing printout is `run()`'s
|
|
6
|
+
* own, through `ensurePaired`, so the code and fingerprint a developer compares
|
|
7
|
+
* in the app are the same lines either way.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
10
|
+
import * as fs from 'node:fs/promises';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { pathToFileURL } from 'node:url';
|
|
13
|
+
import { KeyFile, resolveHost } from './auth.js';
|
|
14
|
+
import { ensurePaired } from './bot.js';
|
|
15
|
+
import { HttpClient, defaultLogger } from './http.js';
|
|
16
|
+
export const USAGE = `aurival — write a bot for Aurival
|
|
17
|
+
|
|
18
|
+
usage:
|
|
19
|
+
aurival init pair this machine and write a starter bot in this folder
|
|
20
|
+
aurival --help this
|
|
21
|
+
|
|
22
|
+
init writes bot.ts when the folder already has TypeScript (a tsconfig.json),
|
|
23
|
+
and bot.js otherwise, so the file it names is one you can actually run. It
|
|
24
|
+
never overwrites an existing bot file.
|
|
25
|
+
`;
|
|
26
|
+
/**
|
|
27
|
+
* The one rule, stated so it can be applied: TypeScript if the folder already
|
|
28
|
+
* has a tsconfig.json, plain JS otherwise. A folder with no TS toolchain gets a
|
|
29
|
+
* file `node` runs as it stands — a `bot.ts` there would be a scaffold whose
|
|
30
|
+
* printed next step does not work.
|
|
31
|
+
*/
|
|
32
|
+
export function starterFilename(dir) {
|
|
33
|
+
return existsSync(path.join(dir, 'tsconfig.json')) ? 'bot.ts' : 'bot.js';
|
|
34
|
+
}
|
|
35
|
+
/** The README's bot, verbatim in behaviour: declare /ping, answer pong. */
|
|
36
|
+
export function starterSource(filename) {
|
|
37
|
+
const imports = filename.endsWith('.ts')
|
|
38
|
+
? "import { Bot, type Context } from 'aurival';"
|
|
39
|
+
: "import { Bot } from 'aurival';";
|
|
40
|
+
const ctx = filename.endsWith('.ts') ? '(ctx: Context)' : '(ctx)';
|
|
41
|
+
return `${imports}
|
|
42
|
+
|
|
43
|
+
const bot = new Bot();
|
|
44
|
+
|
|
45
|
+
bot.command('ping', 'Check that the bot is alive', async ${ctx} => {
|
|
46
|
+
await ctx.reply('pong');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
bot.run();
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
function defaultIO() {
|
|
53
|
+
return {
|
|
54
|
+
cwd: process.cwd(),
|
|
55
|
+
out: (line) => process.stdout.write(line + '\n'),
|
|
56
|
+
err: (line) => process.stderr.write(line + '\n'),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Returns the process exit code. Never calls `process.exit` itself. */
|
|
60
|
+
export async function main(argv, io = defaultIO()) {
|
|
61
|
+
const [command, ...rest] = argv;
|
|
62
|
+
if (command === undefined || command === '--help' || command === '-h') {
|
|
63
|
+
io.out(USAGE);
|
|
64
|
+
return command === undefined ? 2 : 0;
|
|
65
|
+
}
|
|
66
|
+
if (command !== 'init') {
|
|
67
|
+
io.err(`aurival: unknown command ${JSON.stringify(command)}\n`);
|
|
68
|
+
io.err(USAGE);
|
|
69
|
+
return 2;
|
|
70
|
+
}
|
|
71
|
+
if (rest.length > 0) {
|
|
72
|
+
io.err(`aurival: init takes no arguments, got ${JSON.stringify(rest.join(' '))}`);
|
|
73
|
+
return 2;
|
|
74
|
+
}
|
|
75
|
+
return init(io);
|
|
76
|
+
}
|
|
77
|
+
export async function init(io) {
|
|
78
|
+
const filename = starterFilename(io.cwd);
|
|
79
|
+
const target = path.join(io.cwd, filename);
|
|
80
|
+
// Checked BEFORE pairing on purpose: pairing costs the developer a trip to
|
|
81
|
+
// their phone, and burning one to then refuse would be rude.
|
|
82
|
+
if (existsSync(target)) {
|
|
83
|
+
io.err(`aurival: ${filename} already exists here, so init has nothing to do.`);
|
|
84
|
+
io.err('Delete it first, or run init in an empty folder.');
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
const host = resolveHost();
|
|
88
|
+
const log = defaultLogger();
|
|
89
|
+
const keyFile = new KeyFile(null);
|
|
90
|
+
const controller = new AbortController();
|
|
91
|
+
const stop = () => controller.abort();
|
|
92
|
+
process.on('SIGINT', stop);
|
|
93
|
+
process.on('SIGTERM', stop);
|
|
94
|
+
try {
|
|
95
|
+
const { paired } = await ensurePaired(new HttpClient(host, null, log), keyFile, host, log, controller.signal);
|
|
96
|
+
if (!paired)
|
|
97
|
+
io.out(`aurival: this machine is already paired (${keyFile.path}).`);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
process.off('SIGINT', stop);
|
|
101
|
+
process.off('SIGTERM', stop);
|
|
102
|
+
}
|
|
103
|
+
// 'wx': if something raced us to the name between the check above and here,
|
|
104
|
+
// we still refuse rather than overwrite.
|
|
105
|
+
await fs.writeFile(target, starterSource(filename), { encoding: 'utf8', flag: 'wx' });
|
|
106
|
+
// The TS line names a runner we cannot promise is installed: a tsconfig.json
|
|
107
|
+
// says the folder is TypeScript, not that `tsx` is there. Hedged rather than
|
|
108
|
+
// stated, so the one next step is never a command that just fails.
|
|
109
|
+
io.out(filename === 'bot.ts'
|
|
110
|
+
? `Wrote ${filename}. Next: run it with your TypeScript runner, for example npx tsx ${filename}`
|
|
111
|
+
: `Wrote ${filename}. Next: node ${filename}`);
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
// Only when this file is the entry point, so importing it in a test is inert.
|
|
115
|
+
// Through realpath and pathToFileURL because npm installs a bin as a SYMLINK in
|
|
116
|
+
// node_modules/.bin, and a raw string compare misses that by exactly one hop —
|
|
117
|
+
// `npx aurival init` would then print nothing and exit 0.
|
|
118
|
+
function invokedDirectly() {
|
|
119
|
+
const entry = process.argv[1];
|
|
120
|
+
if (entry === undefined)
|
|
121
|
+
return false;
|
|
122
|
+
try {
|
|
123
|
+
return import.meta.url === pathToFileURL(realpathSync(entry)).href;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (invokedDirectly()) {
|
|
130
|
+
main(process.argv.slice(2)).then((code) => {
|
|
131
|
+
process.exitCode = code;
|
|
132
|
+
}, (exc) => {
|
|
133
|
+
process.stderr.write(`aurival: ${exc instanceof Error ? exc.message : String(exc)}\n`);
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ERRORS-V1 as JavaScript errors.
|
|
3
|
+
*
|
|
4
|
+
* One class per `type` (§1), then one subclass per `code` the SDK acts on
|
|
5
|
+
* (errors_v1.go's `errCatalogue`, the closed catalogue). `fromEnvelope` turns a
|
|
6
|
+
* wire envelope into the right instance and never throws itself.
|
|
7
|
+
*/
|
|
8
|
+
/** Base for everything this SDK throws. */
|
|
9
|
+
export declare class AurivalError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
/** A network fault: dial refused, DNS, reset. Never an undici exception. */
|
|
13
|
+
export declare class TransportError extends AurivalError {
|
|
14
|
+
}
|
|
15
|
+
/** The server said something we cannot parse as the documented envelope. */
|
|
16
|
+
export declare class ProtocolError extends AurivalError {
|
|
17
|
+
}
|
|
18
|
+
export interface AurivalAPIErrorInit {
|
|
19
|
+
type: string;
|
|
20
|
+
code: string;
|
|
21
|
+
message: string;
|
|
22
|
+
doc_url: string;
|
|
23
|
+
request_id?: string | null;
|
|
24
|
+
retry_after?: number | null;
|
|
25
|
+
status?: number | null;
|
|
26
|
+
}
|
|
27
|
+
/** One ERRORS-V1 envelope. Every instance carries `code` and `doc_url`. */
|
|
28
|
+
export declare class AurivalAPIError extends AurivalError {
|
|
29
|
+
readonly type: string;
|
|
30
|
+
readonly code: string;
|
|
31
|
+
readonly doc_url: string;
|
|
32
|
+
readonly request_id: string | null;
|
|
33
|
+
readonly retry_after: number | null;
|
|
34
|
+
readonly status: number | null;
|
|
35
|
+
constructor(init: AurivalAPIErrorInit);
|
|
36
|
+
}
|
|
37
|
+
/** `authentication_error` — 401, re-sign and retry once. */
|
|
38
|
+
export declare class AuthenticationError extends AurivalAPIError {
|
|
39
|
+
}
|
|
40
|
+
/** `invalid_request_error` — 400/404/409, never retry. */
|
|
41
|
+
export declare class InvalidRequestError extends AurivalAPIError {
|
|
42
|
+
}
|
|
43
|
+
/** `permission_error` — 403, never retry. */
|
|
44
|
+
export declare class PermissionDeniedError extends AurivalAPIError {
|
|
45
|
+
}
|
|
46
|
+
/** `rate_limit_error` — 429, honour `Retry-After`. */
|
|
47
|
+
export declare class RateLimitError extends AurivalAPIError {
|
|
48
|
+
}
|
|
49
|
+
/** `api_error` — 5xx, our fault, retry with backoff. */
|
|
50
|
+
export declare class APIError extends AurivalAPIError {
|
|
51
|
+
}
|
|
52
|
+
export declare class AccessTokenExpired extends AuthenticationError {
|
|
53
|
+
}
|
|
54
|
+
export declare class AccessTokenInvalid extends AuthenticationError {
|
|
55
|
+
}
|
|
56
|
+
export declare class KeyRevoked extends AuthenticationError {
|
|
57
|
+
}
|
|
58
|
+
export declare class BadAssertion extends AuthenticationError {
|
|
59
|
+
}
|
|
60
|
+
export declare class AssertionExpired extends AuthenticationError {
|
|
61
|
+
}
|
|
62
|
+
export declare class AssertionReplay extends AuthenticationError {
|
|
63
|
+
}
|
|
64
|
+
export declare class BadProof extends AuthenticationError {
|
|
65
|
+
}
|
|
66
|
+
export declare class BadPublicKey extends AuthenticationError {
|
|
67
|
+
}
|
|
68
|
+
export declare class KeyAlreadyPaired extends AuthenticationError {
|
|
69
|
+
}
|
|
70
|
+
export declare class NotFound extends InvalidRequestError {
|
|
71
|
+
}
|
|
72
|
+
export declare class InvalidCommandName extends InvalidRequestError {
|
|
73
|
+
}
|
|
74
|
+
export declare class EmptyText extends InvalidRequestError {
|
|
75
|
+
}
|
|
76
|
+
export declare class TextTooLong extends InvalidRequestError {
|
|
77
|
+
}
|
|
78
|
+
export declare class InvalidJSON extends InvalidRequestError {
|
|
79
|
+
}
|
|
80
|
+
export declare class ParameterMissing extends InvalidRequestError {
|
|
81
|
+
}
|
|
82
|
+
export declare class ParameterInvalid extends InvalidRequestError {
|
|
83
|
+
}
|
|
84
|
+
export declare class UnknownParameter extends InvalidRequestError {
|
|
85
|
+
}
|
|
86
|
+
export declare class IdempotencyKeyReused extends InvalidRequestError {
|
|
87
|
+
}
|
|
88
|
+
export declare class IdempotencyKeyInvalid extends InvalidRequestError {
|
|
89
|
+
}
|
|
90
|
+
export declare class BotLinkNotAllowed extends InvalidRequestError {
|
|
91
|
+
}
|
|
92
|
+
export declare class SessionSuperseded extends InvalidRequestError {
|
|
93
|
+
}
|
|
94
|
+
export declare class FrameTooLarge extends InvalidRequestError {
|
|
95
|
+
}
|
|
96
|
+
export declare class FrameInvalid extends InvalidRequestError {
|
|
97
|
+
}
|
|
98
|
+
export declare class UnknownOperation extends InvalidRequestError {
|
|
99
|
+
}
|
|
100
|
+
export declare class AckUnknownEvent extends InvalidRequestError {
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* `too_many_problems` (SDK-39). BA-R23 was ruled and has since landed on main
|
|
104
|
+
* (`a522dcb4`), so this is a real row rather than a placeholder.
|
|
105
|
+
*/
|
|
106
|
+
export declare class TooManyProblems extends InvalidRequestError {
|
|
107
|
+
}
|
|
108
|
+
export declare class BotSuspended extends PermissionDeniedError {
|
|
109
|
+
}
|
|
110
|
+
export declare class BotPlaygroundOnly extends PermissionDeniedError {
|
|
111
|
+
}
|
|
112
|
+
export declare class RateLimited extends RateLimitError {
|
|
113
|
+
}
|
|
114
|
+
export declare class PairRateLimited extends RateLimitError {
|
|
115
|
+
}
|
|
116
|
+
export declare class SyncRateLimited extends RateLimitError {
|
|
117
|
+
}
|
|
118
|
+
export declare class InternalError extends APIError {
|
|
119
|
+
}
|
|
120
|
+
export declare class ServerRestarting extends APIError {
|
|
121
|
+
}
|
|
122
|
+
export declare class IdleTimeout extends APIError {
|
|
123
|
+
}
|
|
124
|
+
export declare const DOC_URL_PREFIX = "https://bots.aurival.com/docs/errors#";
|
|
125
|
+
export type AurivalAPIErrorClass = new (init: AurivalAPIErrorInit) => AurivalAPIError;
|
|
126
|
+
export declare const TYPE_CLASSES: Readonly<Record<string, AurivalAPIErrorClass>>;
|
|
127
|
+
export declare const CODE_CLASSES: Readonly<Record<string, AurivalAPIErrorClass>>;
|
|
128
|
+
export interface FromEnvelopeOptions {
|
|
129
|
+
status?: number | null;
|
|
130
|
+
retryAfter?: number | null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build an error from an ERRORS-V1 envelope.
|
|
134
|
+
*
|
|
135
|
+
* `payload` is the whole body/frame data: `{"error": {...}}` or already the
|
|
136
|
+
* inner object. Unknown code -> its type's class. Unknown type -> the base
|
|
137
|
+
* `AurivalAPIError`. Never throws.
|
|
138
|
+
*/
|
|
139
|
+
export declare function fromEnvelope(payload: Record<string, unknown>, options?: FromEnvelopeOptions): AurivalAPIError;
|
|
140
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|