@zero-server/cli 0.9.6 → 0.9.8

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @zero-server/cli
2
2
 
3
- > Programmatic access to the `zh` / `zs` CLI.
3
+ > Programmatic access to the `zs` CLI.
4
4
 
5
- Programmatic entry points for the bundled CLI (`zh` / `zs`): scaffolding, migrations, seeding, rollback, status. Useful when embedding the CLI inside your own tooling.
5
+ Programmatic entry points for the bundled CLI (`zs`): scaffolding, migrations, seeding, rollback, status. Useful when embedding the CLI inside your own tooling.
6
6
 
7
7
  ## Install
8
8
 
package/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- // AUTO-GENERATED by .tools/generate-package-stubs.js edit .tools/scope-manifest.js and re-run `npm run packages:generate`.
1
+ // AUTO-GENERATED by .tools/generate-package-stubs.js - edit .tools/scope-manifest.js and re-run `npm run packages:generate`.
2
2
  export * from './types/cli';
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // AUTO-GENERATED by .tools/generate-package-stubs.js edit .tools/scope-manifest.js and re-run `npm run packages:generate`.
1
+ // AUTO-GENERATED by .tools/generate-package-stubs.js - edit .tools/scope-manifest.js and re-run `npm run packages:generate`.
2
2
  'use strict';
3
3
  const lib = require("./lib/cli");
4
4
 
package/lib/cli.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * that exports your database adapter and connection settings.
10
10
  *
11
11
  * @example
12
- * // zero.config.js required by all CLI commands except make:* and help
12
+ * // zero.config.js - required by all CLI commands except make:* and help
13
13
  * module.exports = {
14
14
  * adapter: 'sqlite',
15
15
  * connection: { filename: './app.db' },
@@ -18,13 +18,13 @@
18
18
  * };
19
19
  *
20
20
  * // Run via npx (no global install needed):
21
- * // npx zh migrate
22
- * // npx zh migrate:rollback
23
- * // npx zh migrate:status
24
- * // npx zh seed
25
- * // npx zh make:model User
26
- * // npx zh make:migration create_posts
27
- * // npx zh make:seeder Users
21
+ * // npx zs migrate
22
+ * // npx zs migrate:rollback
23
+ * // npx zs migrate:status
24
+ * // npx zs seed
25
+ * // npx zs make:model User
26
+ * // npx zs make:migration create_posts
27
+ * // npx zs make:seeder Users
28
28
  *
29
29
  * // Or programmatically:
30
30
  * const { runCLI } = require('@zero-server/sdk');
@@ -150,6 +150,15 @@ class CLI
150
150
  */
151
151
  async run()
152
152
  {
153
+ // WebRTC subcommands - delegate the whole `webrtc:*` namespace to the
154
+ // webrtc CLI module so the top-level dispatcher stays small.
155
+ if (typeof this.command === 'string' && this.command.startsWith('webrtc:'))
156
+ {
157
+ const { runWebRTCCommand } = require('@zero-server/webrtc');
158
+ await runWebRTCCommand(this.command.slice('webrtc:'.length), this.flags);
159
+ return;
160
+ }
161
+
153
162
  const commands = {
154
163
  'migrate': () => this._migrate(),
155
164
  'migrate:rollback': () => this._rollback(),
@@ -206,7 +215,7 @@ class CLI
206
215
  throw new Error(
207
216
  'No configuration file found.\n' +
208
217
  'Create a zero.config.js with database and migration settings.\n' +
209
- 'See "zh help" for examples.'
218
+ 'See "zs help" for examples.'
210
219
  );
211
220
  }
212
221
 
@@ -421,8 +430,8 @@ class CLI
421
430
  const status = await migrator.status();
422
431
  if (status.executed.includes(lastMigration.name))
423
432
  {
424
- console.error(red(`Cannot remove "${lastMigration.name}" it has already been applied.`));
425
- console.error(dim('Run "zh migrate:rollback" first, then try again.'));
433
+ console.error(red(`Cannot remove "${lastMigration.name}" - it has already been applied.`));
434
+ console.error(dim('Run "zs migrate:rollback" first, then try again.'));
426
435
  process.exitCode = 1;
427
436
  await db.close();
428
437
  return;
@@ -510,7 +519,7 @@ class CLI
510
519
  const name = this.args.find(a => !a.startsWith('-'));
511
520
  if (!name)
512
521
  {
513
- console.error(red('Usage: zh make:model <Name>'));
522
+ console.error(red('Usage: zs make:model <Name>'));
514
523
  process.exitCode = 1;
515
524
  return;
516
525
  }
@@ -566,7 +575,7 @@ module.exports = ${className};
566
575
  const name = this.args.find(a => !a.startsWith('-'));
567
576
  if (!name)
568
577
  {
569
- console.error(red('Usage: zh make:migration <name>'));
578
+ console.error(red('Usage: zs make:migration <name>'));
570
579
  process.exitCode = 1;
571
580
  return;
572
581
  }
@@ -645,7 +654,7 @@ module.exports = {
645
654
 
646
655
  if (hasNoChanges(changes))
647
656
  {
648
- console.log(dim('No schema changes detected nothing to migrate.'));
657
+ console.log(dim('No schema changes detected - nothing to migrate.'));
649
658
  return;
650
659
  }
651
660
 
@@ -692,7 +701,7 @@ module.exports = {
692
701
  const name = this.args.find(a => !a.startsWith('-'));
693
702
  if (!name)
694
703
  {
695
- console.error(red('Usage: zh make:seeder <name>'));
704
+ console.error(red('Usage: zs make:seeder <name>'));
696
705
  process.exitCode = 1;
697
706
  return;
698
707
  }
@@ -742,9 +751,9 @@ module.exports = ${className};
742
751
  _help()
743
752
  {
744
753
  console.log(`
745
- ${bold('zh CLI')} zero-server ORM tooling
754
+ ${bold('zs CLI')} - zero-server ORM tooling
746
755
 
747
- ${bold('Usage:')} npx zh <command> [options]
756
+ ${bold('Usage:')} npx zs <command> [options]
748
757
 
749
758
  ${bold('Commands:')}
750
759
 
@@ -761,6 +770,12 @@ ${bold('Commands:')}
761
770
  ${cyan('make:migration')} <n> Auto-generate migration from model changes
762
771
  ${cyan('make:seeder')} <name> Scaffold a new seeder file
763
772
 
773
+ ${cyan('webrtc:stun')} Run a STUN binding probe, print public addr
774
+ ${cyan('webrtc:turn-creds')} Issue ephemeral TURN credentials
775
+ ${cyan('webrtc:join-token')} Sign a signaling join token
776
+ ${cyan('webrtc:verify-token')} Verify and decode a join token
777
+ ${cyan('webrtc:help')} Show webrtc subcommand help
778
+
764
779
  ${cyan('help')} Show this help message
765
780
  ${cyan('version')} Show version
766
781
 
@@ -788,19 +803,19 @@ ${bold('Config file:')} ${dim('zero.config.js (or .zero-server.js / legacy .zero
788
803
 
789
804
  ${bold('Auto-generated migrations:')}
790
805
 
791
- ${dim('$')} npx zh make:migration create_users ${dim('# detects new User model → generates CREATE TABLE')}
792
- ${dim('$')} npx zh make:migration add_email ${dim('# detects new email column → generates ADD COLUMN')}
793
- ${dim('$')} npx zh make:migration --empty init ${dim('# blank migration (manual mode)')}
794
- ${dim('$')} npx zh migrate ${dim('# apply pending migrations')}
795
- ${dim('$')} npx zh migrate:remove ${dim('# undo last make:migration')}
806
+ ${dim('$')} npx zs make:migration create_users ${dim('# detects new User model → generates CREATE TABLE')}
807
+ ${dim('$')} npx zs make:migration add_email ${dim('# detects new email column → generates ADD COLUMN')}
808
+ ${dim('$')} npx zs make:migration --empty init ${dim('# blank migration (manual mode)')}
809
+ ${dim('$')} npx zs migrate ${dim('# apply pending migrations')}
810
+ ${dim('$')} npx zs migrate:remove ${dim('# undo last make:migration')}
796
811
 
797
812
  ${bold('Examples:')}
798
813
 
799
- ${dim('$')} npx zh make:model User ${dim('# creates models/User.js')}
800
- ${dim('$')} npx zh make:migration create_users ${dim('# auto-generates from models')}
801
- ${dim('$')} npx zh migrate ${dim('# runs all pending migrations')}
802
- ${dim('$')} npx zh migrate --config=db.config.js
803
- ${dim('$')} npx zh seed ${dim('# runs all seeders')}
814
+ ${dim('$')} npx zs make:model User ${dim('# creates models/User.js')}
815
+ ${dim('$')} npx zs make:migration create_users ${dim('# auto-generates from models')}
816
+ ${dim('$')} npx zs migrate ${dim('# runs all pending migrations')}
817
+ ${dim('$')} npx zs migrate --config=db.config.js
818
+ ${dim('$')} npx zs seed ${dim('# runs all seeders')}
804
819
  `);
805
820
  }
806
821
 
@@ -810,7 +825,7 @@ ${bold('Examples:')}
810
825
  _version()
811
826
  {
812
827
  const pkg = require('../package.json');
813
- console.log(`zh v${pkg.version} (zero-server)`);
828
+ console.log(`zs v${pkg.version} (zero-server)`);
814
829
  }
815
830
  }
816
831
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zero-server/cli",
3
- "version": "0.9.6",
4
- "description": "Programmatic access to the `zh` / `zs` CLI.",
3
+ "version": "0.9.8",
4
+ "description": "Programmatic access to the `zs` CLI.",
5
5
  "keywords": [
6
6
  "zero-server",
7
7
  "zero-server",
@@ -45,10 +45,11 @@
45
45
  },
46
46
  "sideEffects": false,
47
47
  "dependencies": {
48
- "@zero-server/orm": "0.9.6"
48
+ "@zero-server/orm": "0.9.8",
49
+ "@zero-server/webrtc": "0.9.8"
49
50
  },
50
51
  "peerDependencies": {
51
- "@zero-server/sdk": ">=0.9.6"
52
+ "@zero-server/sdk": ">=0.9.8"
52
53
  },
53
54
  "peerDependenciesMeta": {
54
55
  "@zero-server/sdk": {
package/types/body.d.ts CHANGED
@@ -1,14 +1,82 @@
1
- // Re-exports for @zero-server/body body parser types
2
- export {
3
- BodyParserOptions,
4
- JsonParserOptions,
5
- UrlencodedParserOptions,
6
- TextParserOptions,
7
- MultipartOptions,
8
- MultipartFile,
9
- json,
10
- urlencoded,
11
- text,
12
- raw,
13
- multipart,
14
- } from './middleware';
1
+ // TypeScript declarations for the bundled body parsers
2
+ // (`json`, `urlencoded`, `text`, `raw`, `multipart`).
3
+ //
4
+ // These live in `lib/body/*` at runtime and are surfaced both via the
5
+ // top-level SDK and the standalone `@zero-server/body` scope. They are
6
+ // declared here (not in `./middleware`) so the body-parser package has
7
+ // a self-contained declaration file.
8
+
9
+ import { MiddlewareFunction } from './middleware';
10
+ import { Request } from './request';
11
+ import { Response } from './response';
12
+
13
+ export interface BodyParserOptions {
14
+ /** Max body size (e.g. '10kb', '1mb'). Default: '1mb'. */
15
+ limit?: string | number;
16
+ /** Content-Type(s) to match. Accepts a string, an array of strings, or a predicate function. */
17
+ type?: string | string[] | ((ct: string) => boolean);
18
+ /** Reject non-HTTPS requests with 403. */
19
+ requireSecure?: boolean;
20
+ /**
21
+ * Verification callback invoked with the raw buffer before parsing.
22
+ * Throw an error to reject the request with 403.
23
+ * Useful for webhook signature verification (e.g. Stripe, GitHub).
24
+ */
25
+ verify?: (req: Request, res: Response, buf: Buffer, encoding: string) => void;
26
+ /** Decompress gzip/deflate/br request bodies. Default: true. When false, compressed bodies return 415. */
27
+ inflate?: boolean;
28
+ }
29
+
30
+ export interface JsonParserOptions extends BodyParserOptions {
31
+ /** JSON.parse reviver function. */
32
+ reviver?: (key: string, value: any) => any;
33
+ /** Reject non-object/array roots. Default: true. */
34
+ strict?: boolean;
35
+ }
36
+
37
+ export interface UrlencodedParserOptions extends BodyParserOptions {
38
+ /** Enable nested bracket parsing. Default: false. */
39
+ extended?: boolean;
40
+ /** Max number of parameters. Default: 1000. Prevents parameter flooding DoS. */
41
+ parameterLimit?: number;
42
+ /** Max nesting depth for bracket syntax. Default: 32. Prevents deep-nesting DoS. */
43
+ depth?: number;
44
+ }
45
+
46
+ export interface TextParserOptions extends BodyParserOptions {
47
+ /** Fallback character encoding when Content-Type has no charset. Default: 'utf8'. */
48
+ encoding?: BufferEncoding;
49
+ }
50
+
51
+ export interface MultipartOptions {
52
+ /** Upload directory (default: OS temp). */
53
+ dir?: string;
54
+ /** Maximum size per file in bytes. */
55
+ maxFileSize?: number;
56
+ /** Reject non-HTTPS requests with 403. */
57
+ requireSecure?: boolean;
58
+ /** Maximum number of non-file fields. Default: 1000. */
59
+ maxFields?: number;
60
+ /** Maximum number of uploaded files. Default: 10. */
61
+ maxFiles?: number;
62
+ /** Maximum size of a single field value in bytes. Default: 1 MB. */
63
+ maxFieldSize?: number;
64
+ /** Whitelist of allowed MIME types for uploaded files (e.g. ['image/png', 'image/jpeg']). */
65
+ allowedMimeTypes?: string[];
66
+ /** Maximum combined size of all uploaded files in bytes. */
67
+ maxTotalSize?: number;
68
+ }
69
+
70
+ export interface MultipartFile {
71
+ originalFilename: string;
72
+ storedName: string;
73
+ path: string;
74
+ contentType: string;
75
+ size: number;
76
+ }
77
+
78
+ export function json(options?: JsonParserOptions): MiddlewareFunction;
79
+ export function urlencoded(options?: UrlencodedParserOptions): MiddlewareFunction;
80
+ export function text(options?: TextParserOptions): MiddlewareFunction;
81
+ export function raw(options?: BodyParserOptions): MiddlewareFunction;
82
+ export function multipart(options?: MultipartOptions): MiddlewareFunction;
package/types/cli.d.ts CHANGED
@@ -1,2 +1,40 @@
1
- // Re-exports for @zero-server/cli CLI runner types
2
- export { CLI, runCLI } from './orm';
1
+ // TypeScript declarations for the bundled CLI runner (`zs` / `zh`).
2
+ //
3
+ // The CLI lives in `lib/cli.js` and is published both as the `zs` /
4
+ // `zh` bin scripts and as a programmatic API on the SDK. It dispatches
5
+ // ORM subcommands (`migrate`, `seed`, `make:*`) to `@zero-server/orm`
6
+ // and `webrtc:*` subcommands to `@zero-server/webrtc`, but the runner
7
+ // itself is scope-neutral - hence its own declaration file.
8
+
9
+ /**
10
+ * CLI runner for the bundled `zs` command.
11
+ *
12
+ * Parses `process.argv`-style input, resolves a config file
13
+ * (`zero.config.js` / `.zero-server.js` / `.zero-http.js`), and
14
+ * dispatches to the matching subcommand handler.
15
+ */
16
+ export class CLI {
17
+ constructor(argv?: string[]);
18
+
19
+ /** The first positional argument (subcommand name). Defaults to `"help"`. */
20
+ readonly command: string;
21
+
22
+ /** Remaining positional arguments after the subcommand. */
23
+ readonly args: string[];
24
+
25
+ /** Parsed `--flag=value` and `-f value` pairs. */
26
+ readonly flags: Map<string, string>;
27
+
28
+ /** Execute the parsed command. Sets `process.exitCode` on failure. */
29
+ run(): Promise<void>;
30
+ }
31
+
32
+ /**
33
+ * One-shot helper: `new CLI(argv).run()`.
34
+ *
35
+ * @example
36
+ * const { runCLI } = require('@zero-server/sdk');
37
+ * await runCLI(['migrate']);
38
+ * await runCLI(['make:model', 'User', '--dir=src/models']);
39
+ */
40
+ export function runCLI(argv?: string[]): Promise<void>;
package/types/index.d.ts CHANGED
@@ -11,6 +11,18 @@ export { RouterInstance, RouteChain, RouteEntry, RouteInfo, RouteOptions, RouteH
11
11
  export { Request, RangeResult } from './request';
12
12
  export { Response, SendFileOptions, CookieOptions, PushOptions } from './response';
13
13
  export { SSEOptions, SSEStream } from './sse';
14
+ export {
15
+ createWebRTC, SignalingHub, Room as WebRTCRoom, Peer as WebRTCPeer,
16
+ parseSdp, stringifySdp, parseCandidate, stringifyCandidate,
17
+ stunBinding, encodeBindingRequest, decodeMessage,
18
+ encodeXorMappedAddress, decodeXorMappedAddress,
19
+ STUN_MAGIC_COOKIE, STUN_METHOD, STUN_CLASS, STUN_ATTR,
20
+ issueTurnCredentials, TurnServer, SfuAdapter,
21
+ signJoinToken, verifyJoinToken,
22
+ WebRTCOptions, RoomOptions as WebRTCRoomOptions, PeerInfo, SignalingMessage,
23
+ IceServerConfig, TurnCredentials, IssueTurnCredentialsOptions, ClusterAdapter as WebRTCClusterAdapter,
24
+ WebRTCError, SignalingError, IceError, TurnError, SdpError,
25
+ } from './webrtc';
14
26
  export { LifecycleManager, LifecycleState, LIFECYCLE_STATE } from './lifecycle';
15
27
  export { ClusterManager, ClusterOptions, cluster } from './cluster';
16
28
  export {
@@ -85,8 +97,8 @@ export {
85
97
  StoredProcedure, StoredProcedureOptions, ProcedureParam,
86
98
  StoredFunction, StoredFunctionOptions,
87
99
  TriggerManager, TriggerDefinition,
88
- CLI, runCLI,
89
100
  } from './orm';
101
+ export { CLI, runCLI } from './cli';
90
102
  // Re-export validate from orm as schemaValidate to avoid collision with middleware validate
91
103
  export { validate as schemaValidate } from './orm';
92
104
  export {
@@ -149,7 +161,8 @@ import { Database, Model, Query } from './orm';
149
161
  import { TYPES, validateFKAction, validateCheck } from './orm';
150
162
  import { Migrator, QueryCache, Seeder, SeederRunner, Factory, Fake, defineMigration } from './orm';
151
163
  import { QueryProfiler, ReplicaManager } from './orm';
152
- import { TenantManager, AuditLog, PluginManager, StoredProcedure, StoredFunction, TriggerManager, CLI, runCLI } from './orm';
164
+ import { TenantManager, AuditLog, PluginManager, StoredProcedure, StoredFunction, TriggerManager } from './orm';
165
+ import { CLI, runCLI } from './cli';
153
166
  import { LifecycleManager, LIFECYCLE_STATE } from './lifecycle';
154
167
  import { ClusterManager, cluster as clusterize } from './cluster';
155
168
  import {
@@ -294,10 +307,10 @@ declare const zeroServer: {
294
307
  LIFECYCLE_STATE: typeof LIFECYCLE_STATE;
295
308
  ClusterManager: typeof ClusterManager;
296
309
  cluster: typeof clusterize;
297
- // Observability Structured Logging
310
+ // Observability - Structured Logging
298
311
  Logger: typeof Logger;
299
312
  structuredLogger: typeof structuredLogger;
300
- // Observability Metrics
313
+ // Observability - Metrics
301
314
  Counter: typeof Counter;
302
315
  Gauge: typeof Gauge;
303
316
  Histogram: typeof Histogram;
@@ -306,14 +319,14 @@ declare const zeroServer: {
306
319
  createDefaultMetrics: typeof createDefaultMetrics;
307
320
  metricsMiddleware: typeof metricsMiddleware;
308
321
  metricsEndpoint: typeof metricsEndpointHandler;
309
- // Observability Tracing
322
+ // Observability - Tracing
310
323
  Span: typeof Span;
311
324
  Tracer: typeof Tracer;
312
325
  parseTraceparent: typeof parseTraceparent;
313
326
  formatTraceparent: typeof formatTraceparent;
314
327
  tracingMiddleware: typeof tracingMiddleware;
315
328
  instrumentFetch: typeof instrumentFetch;
316
- // Observability Health Checks
329
+ // Observability - Health Checks
317
330
  healthCheck: typeof healthCheck;
318
331
  createHealthHandlers: typeof createHealthHandlers;
319
332
  memoryCheck: typeof memoryCheck;
@@ -21,77 +21,23 @@ export interface CorsOptions {
21
21
  export function cors(options?: CorsOptions): MiddlewareFunction;
22
22
 
23
23
  // --- Body Parsers ------------------------------------------------
24
-
25
- export interface BodyParserOptions {
26
- /** Max body size (e.g. '10kb', '1mb'). Default: '1mb'. */
27
- limit?: string | number;
28
- /** Content-Type(s) to match. Accepts a string, an array of strings, or a predicate function. */
29
- type?: string | string[] | ((ct: string) => boolean);
30
- /** Reject non-HTTPS requests with 403. */
31
- requireSecure?: boolean;
32
- /**
33
- * Verification callback invoked with the raw buffer before parsing.
34
- * Throw an error to reject the request with 403.
35
- * Useful for webhook signature verification (e.g. Stripe, GitHub).
36
- */
37
- verify?: (req: import('./request').Request, res: import('./response').Response, buf: Buffer, encoding: string) => void;
38
- /** Decompress gzip/deflate/br request bodies. Default: true. When false, compressed bodies return 415. */
39
- inflate?: boolean;
40
- }
41
-
42
- export interface JsonParserOptions extends BodyParserOptions {
43
- /** JSON.parse reviver function. */
44
- reviver?: (key: string, value: any) => any;
45
- /** Reject non-object/array roots. Default: true. */
46
- strict?: boolean;
47
- }
48
-
49
- export interface UrlencodedParserOptions extends BodyParserOptions {
50
- /** Enable nested bracket parsing. Default: false. */
51
- extended?: boolean;
52
- /** Max number of parameters. Default: 1000. Prevents parameter flooding DoS. */
53
- parameterLimit?: number;
54
- /** Max nesting depth for bracket syntax. Default: 32. Prevents deep-nesting DoS. */
55
- depth?: number;
56
- }
57
-
58
- export interface TextParserOptions extends BodyParserOptions {
59
- /** Fallback character encoding when Content-Type has no charset. Default: 'utf8'. */
60
- encoding?: BufferEncoding;
61
- }
62
-
63
- export interface MultipartOptions {
64
- /** Upload directory (default: OS temp). */
65
- dir?: string;
66
- /** Maximum size per file in bytes. */
67
- maxFileSize?: number;
68
- /** Reject non-HTTPS requests with 403. */
69
- requireSecure?: boolean;
70
- /** Maximum number of non-file fields. Default: 1000. */
71
- maxFields?: number;
72
- /** Maximum number of uploaded files. Default: 10. */
73
- maxFiles?: number;
74
- /** Maximum size of a single field value in bytes. Default: 1 MB. */
75
- maxFieldSize?: number;
76
- /** Whitelist of allowed MIME types for uploaded files (e.g. ['image/png', 'image/jpeg']). */
77
- allowedMimeTypes?: string[];
78
- /** Maximum combined size of all uploaded files in bytes. */
79
- maxTotalSize?: number;
80
- }
81
-
82
- export interface MultipartFile {
83
- originalFilename: string;
84
- storedName: string;
85
- path: string;
86
- contentType: string;
87
- size: number;
88
- }
89
-
90
- export function json(options?: JsonParserOptions): MiddlewareFunction;
91
- export function urlencoded(options?: UrlencodedParserOptions): MiddlewareFunction;
92
- export function text(options?: TextParserOptions): MiddlewareFunction;
93
- export function raw(options?: BodyParserOptions): MiddlewareFunction;
94
- export function multipart(options?: MultipartOptions): MiddlewareFunction;
24
+ // Declarations live in `./body` so the standalone `@zero-server/body`
25
+ // package has its own self-contained type file. Re-exported here so
26
+ // callers using the aggregate middleware surface continue to work.
27
+
28
+ export {
29
+ BodyParserOptions,
30
+ JsonParserOptions,
31
+ UrlencodedParserOptions,
32
+ TextParserOptions,
33
+ MultipartOptions,
34
+ MultipartFile,
35
+ json,
36
+ urlencoded,
37
+ text,
38
+ raw,
39
+ multipart,
40
+ } from './body';
95
41
 
96
42
  // --- Rate Limiting -----------------------------------------------
97
43
 
@@ -136,7 +82,7 @@ export interface CompressOptions {
136
82
  level?: number;
137
83
  /** Force specific encoding(s). */
138
84
  encoding?: string | string[];
139
- /** Filter function return false to skip compression. */
85
+ /** Filter function - return false to skip compression. */
140
86
  filter?: (req: Request, res: Response) => boolean;
141
87
  }
142
88
 
package/types/orm.d.ts CHANGED
@@ -29,7 +29,7 @@ export interface SchemaColumnDef {
29
29
  enum?: string[];
30
30
  /** Allowed values (set type). */
31
31
  values?: string[];
32
- /** Mass-assignment protection exclude from bulk writes. */
32
+ /** Mass-assignment protection - exclude from bulk writes. */
33
33
  guarded?: boolean;
34
34
  /** Precision for decimal types. */
35
35
  precision?: number;
@@ -229,7 +229,7 @@ export class Query {
229
229
  take(n: number): Query;
230
230
  /** Alias for offset (LINQ naming). */
231
231
  skip(n: number): Query;
232
- /** Alias for exec explicitly convert to array. */
232
+ /** Alias for exec - explicitly convert to array. */
233
233
  toArray(): Promise<Model[]>;
234
234
  /** Shorthand for orderBy(field, 'desc'). */
235
235
  orderByDesc(field: string): Query;
@@ -260,7 +260,7 @@ export class Query {
260
260
  /** Inject a raw WHERE clause for SQL adapters (ignored by memory/mongo). */
261
261
  whereRaw(sql: string, ...params: any[]): Query;
262
262
 
263
- /** Thenable support `await query`. */
263
+ /** Thenable support - `await query`. */
264
264
  then<TResult1 = Model[], TResult2 = never>(
265
265
  onfulfilled?: ((value: Model[]) => TResult1 | PromiseLike<TResult1>) | null,
266
266
  onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
@@ -1875,13 +1875,4 @@ export class TriggerManager {
1875
1875
  get(name: string): TriggerDefinition | undefined;
1876
1876
  }
1877
1877
 
1878
- // --- CLI (Phase 4) --------------------------------------------------
1879
-
1880
- export class CLI {
1881
- constructor(argv?: string[]);
1882
- /** Run the CLI command. */
1883
- run(): Promise<void>;
1884
- }
1885
-
1886
- /** Create and run the CLI. */
1887
- export function runCLI(argv?: string[]): Promise<void>;
1878
+ // CLI declarations live in `./cli` (re-exported from `./index`).
@@ -31,7 +31,7 @@ export interface Request {
31
31
  readonly ips: string[];
32
32
  /** `true` when the connection is over TLS (trust-proxy-aware). */
33
33
  readonly secure: boolean;
34
- /** Protocol string `'https'` or `'http'` (trust-proxy-aware). */
34
+ /** Protocol string - `'https'` or `'http'` (trust-proxy-aware). */
35
35
  readonly protocol: 'http' | 'https';
36
36
  /** HTTP version string (e.g. '1.1', '2.0'). */
37
37
  httpVersion: string;
@@ -49,7 +49,7 @@ export interface Request {
49
49
  id?: string;
50
50
  /** Whether the request timed out (populated by timeout middleware). */
51
51
  timedOut?: boolean;
52
- /** The original URL as received never rewritten by middleware. */
52
+ /** The original URL as received - never rewritten by middleware. */
53
53
  originalUrl: string;
54
54
  /** The URL path on which the current router was mounted. */
55
55
  baseUrl: string;
@@ -83,7 +83,7 @@ export interface Request {
83
83
  subdomains(offset?: number): string[];
84
84
 
85
85
  /**
86
- * Content negotiation check which types the client accepts.
86
+ * Content negotiation - check which types the client accepts.
87
87
  */
88
88
  accepts(...types: string[]): string | false;
89
89
 
@@ -0,0 +1,501 @@
1
+ /**
2
+ * TypeScript surface for @zero-server/webrtc.
3
+ *
4
+ * Mirrors the runtime surface exported from `lib/webrtc/index.js` and
5
+ * re-exported from the top-level SDK in `index.js`. Every entry listed
6
+ * in `.tools/scope-manifest.js` under the `webrtc` scope MUST have a
7
+ * matching declaration here - this is enforced by
8
+ * `test/packages/webrtc-types.test.js`.
9
+ */
10
+
11
+ import type { EventEmitter } from 'node:events';
12
+ import type { KeyObject } from 'node:crypto';
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Shared option / config types
16
+ // ---------------------------------------------------------------------------
17
+
18
+ export interface IceServerConfig {
19
+ urls: string | string[];
20
+ username?: string;
21
+ credential?: string;
22
+ }
23
+
24
+ export interface TurnCredentials {
25
+ urls: string[];
26
+ username: string;
27
+ credential: string;
28
+ ttl: number;
29
+ }
30
+
31
+ export interface IssueTurnCredentialsOptions {
32
+ secret: string;
33
+ userId: string;
34
+ ttl?: string | number;
35
+ servers: string[];
36
+ realm?: string;
37
+ }
38
+
39
+ export interface SignalingHubOptions {
40
+ maxSdpSize?: number;
41
+ maxCandidatesPerOffer?: number;
42
+ peerMessageRate?: number;
43
+ maxProtocolErrors?: number;
44
+ ipAttachRate?: number;
45
+ originAllowlist?: string[];
46
+ joinTokenSecret?: string | Buffer;
47
+ autoCreateRooms?: boolean;
48
+ }
49
+
50
+ export interface WebRTCOptions extends SignalingHubOptions {
51
+ path?: string;
52
+ iceServers?: IceServerConfig[] | 'auto';
53
+ }
54
+
55
+ export interface PeerAttachInfo {
56
+ user?: unknown;
57
+ ip?: string;
58
+ origin?: string;
59
+ [extra: string]: unknown;
60
+ }
61
+
62
+ export interface PeerTransport {
63
+ send(data: string): void;
64
+ on(event: 'message' | 'close', cb: (...args: unknown[]) => void): void;
65
+ close(code?: number, reason?: string): void;
66
+ }
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // SDP / ICE helpers
70
+ // ---------------------------------------------------------------------------
71
+
72
+ export interface ParsedSdpMedia {
73
+ type: string;
74
+ port: number;
75
+ proto: string;
76
+ formats: string[];
77
+ iceUfrag?: string;
78
+ icePwd?: string;
79
+ fingerprint?: { algorithm: string; hash: string };
80
+ candidates?: ParsedIceCandidate[];
81
+ [key: string]: unknown;
82
+ }
83
+
84
+ export interface ParsedSdp {
85
+ version: number;
86
+ origin: Record<string, unknown>;
87
+ sessionName: string;
88
+ media: ParsedSdpMedia[];
89
+ [key: string]: unknown;
90
+ }
91
+
92
+ export interface ParsedIceCandidate {
93
+ foundation: string;
94
+ component: number;
95
+ transport: string;
96
+ priority: number;
97
+ address: string;
98
+ port: number;
99
+ type: string;
100
+ relatedAddress?: string;
101
+ relatedPort?: number;
102
+ tcpType?: string;
103
+ [key: string]: unknown;
104
+ }
105
+
106
+ export declare function parseSdp(sdp: string, opts?: { maxBytes?: number }): ParsedSdp;
107
+ export declare function stringifySdp(parsed: ParsedSdp): string;
108
+
109
+ export declare function parseCandidate(line: string): ParsedIceCandidate;
110
+ export declare function stringifyCandidate(parsed: ParsedIceCandidate): string;
111
+ export declare function filterCandidates(
112
+ candidates: ParsedIceCandidate[],
113
+ opts?: { allowPrivate?: boolean; allowLoopback?: boolean; allowLinkLocal?: boolean; allowMdns?: boolean }
114
+ ): ParsedIceCandidate[];
115
+
116
+ export declare function isPrivateIp(addr: string): boolean;
117
+ export declare function isLoopbackIp(addr: string): boolean;
118
+ export declare function isLinkLocalIp(addr: string): boolean;
119
+ export declare function isMdnsHostname(addr: string): boolean;
120
+
121
+ export declare const CANDIDATE_TYPES: Readonly<{ HOST: string; SRFLX: string; PRFLX: string; RELAY: string }>;
122
+ export declare const TCP_TYPES: Readonly<{ ACTIVE: string; PASSIVE: string; SO: string }>;
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // STUN / TURN
126
+ // ---------------------------------------------------------------------------
127
+
128
+ export declare function stunBinding(opts: {
129
+ host: string;
130
+ port?: number;
131
+ timeoutMs?: number;
132
+ retries?: number;
133
+ socketType?: 'udp4' | 'udp6';
134
+ }): Promise<{ family: 4 | 6; address: string; port: number }>;
135
+
136
+ export declare function encodeBindingRequest(transactionId?: Buffer): { buffer: Buffer; transactionId: Buffer };
137
+ export declare function decodeMessage(buf: Buffer): {
138
+ method: number;
139
+ class: number;
140
+ transactionId: Buffer;
141
+ attributes: Array<{ type: number; value: Buffer }>;
142
+ };
143
+ export declare function encodeXorMappedAddress(address: string, port: number, transactionId: Buffer): Buffer;
144
+ export declare function decodeXorMappedAddress(value: Buffer, transactionId: Buffer): { family: 4 | 6; address: string; port: number };
145
+
146
+ export declare const STUN_MAGIC_COOKIE: number;
147
+ export declare const STUN_METHOD: Readonly<{ BINDING: number }>;
148
+ export declare const STUN_CLASS: Readonly<{ REQUEST: number; INDICATION: number; SUCCESS: number; ERROR: number }>;
149
+ export declare const STUN_ATTR: Readonly<{ MAPPED_ADDRESS: number; XOR_MAPPED_ADDRESS: number; ERROR_CODE: number; SOFTWARE: number }>;
150
+
151
+ export declare function issueTurnCredentials(opts: IssueTurnCredentialsOptions): TurnCredentials;
152
+
153
+ export declare class TurnServer {
154
+ constructor(opts: {
155
+ secret: string;
156
+ realm?: string;
157
+ listeners: Array<{ proto: 'udp' | 'tcp' | 'tls'; port: number; host?: string; tls?: { cert: Buffer; key: Buffer } }>;
158
+ quotas?: { maxAllocationsPerUser?: number; maxBytesPerMinute?: number };
159
+ defaultLifetime?: number;
160
+ maxLifetime?: number;
161
+ relayHost?: string;
162
+ });
163
+ readonly realm: string;
164
+ start(): Promise<void>;
165
+ stop(): Promise<void>;
166
+ address(): { address: string; port: number } | null;
167
+ on(event: 'allocation', listener: (ev: { userId: string; relay: { address: string; port: number }; client: { address: string; port: number } }) => void): this;
168
+ on(event: 'deallocation', listener: (ev: { userId: string; client: { address: string; port: number }; reason?: string }) => void): this;
169
+ on(event: 'error', listener: (err: Error) => void): this;
170
+ on(event: string, listener: (...args: unknown[]) => void): this;
171
+ }
172
+
173
+ // ---------------------------------------------------------------------------
174
+ // Signaling core
175
+ // ---------------------------------------------------------------------------
176
+
177
+ export type PeerState = 'stable' | 'have-local-offer' | 'have-remote-offer';
178
+
179
+ export declare const PEER_STATE: Readonly<{
180
+ STABLE: 'stable';
181
+ HAVE_LOCAL_OFFER: 'have-local-offer';
182
+ HAVE_REMOTE_OFFER: 'have-remote-offer';
183
+ }>;
184
+
185
+ export declare class Peer {
186
+ readonly id: string;
187
+ readonly user: unknown;
188
+ readonly ip: string | null;
189
+ readonly transport: PeerTransport;
190
+ state: PeerState;
191
+ room: Room | null;
192
+ errors: number;
193
+ readonly connectedAt: number;
194
+ closed: boolean;
195
+ e2ee?: E2eeChannel;
196
+ constructor(transport: PeerTransport, info?: PeerAttachInfo);
197
+ send(type: string, payload?: object): void;
198
+ sendError(code: string, message: string): void;
199
+ close(code?: number, reason?: string): void;
200
+ }
201
+
202
+ export declare class Room {
203
+ readonly name: string;
204
+ readonly hub: SignalingHub | null;
205
+ isOpen: boolean;
206
+ constructor(name: string, opts?: { hub?: SignalingHub });
207
+ open(): this;
208
+ require(fn: (peer: Peer) => boolean | Promise<boolean>): this;
209
+ canPublish(fn: (peer: Peer) => boolean): this;
210
+ canSubscribe(fn: (peer: Peer) => boolean): this;
211
+ readonly size: number;
212
+ peers(): Peer[];
213
+ canJoin(peer: Peer): boolean | Promise<boolean>;
214
+ broadcast(type: string, payload?: object, exceptPeerId?: string): void;
215
+ close(reason?: string): void;
216
+ }
217
+
218
+ export interface SignalingHubEvents {
219
+ join: (ev: { peer: Peer; room: Room }) => void;
220
+ leave: (ev: { peer: Peer; room: Room }) => void;
221
+ offer: (ev: { peer: Peer; target: Peer | null; room: Room; sdp: string }) => void;
222
+ answer: (ev: { peer: Peer; target: Peer | null; room: Room; sdp: string }) => void;
223
+ signal: (ev: { peer: Peer; type: string }) => void;
224
+ joinFailed: (ev: { peer: Peer; reason: string; room?: string }) => void;
225
+ publishFailed: (ev: { peer: Peer; reason: string; room: string }) => void;
226
+ subscribeFailed: (ev: { peer: Peer; reason: string; room: string }) => void;
227
+ wireError: (ev: { peer: Peer; code: string }) => void;
228
+ e2eeKey: (ev: { peer: Peer; room: Room; epoch: number; key: string }) => void;
229
+ clusterError: (err: Error) => void;
230
+ }
231
+
232
+ export declare class SignalingHub extends EventEmitter {
233
+ constructor(opts?: SignalingHubOptions);
234
+ readonly size: number;
235
+ room(name: string): Room;
236
+ rooms(): Room[];
237
+ attach(transport: PeerTransport, info?: PeerAttachInfo): Peer;
238
+ close(): void;
239
+ on<E extends keyof SignalingHubEvents>(event: E, listener: SignalingHubEvents[E]): this;
240
+ on(event: string, listener: (...args: unknown[]) => void): this;
241
+ off<E extends keyof SignalingHubEvents>(event: E, listener: SignalingHubEvents[E]): this;
242
+ off(event: string, listener: (...args: unknown[]) => void): this;
243
+ emit<E extends keyof SignalingHubEvents>(event: E, ...args: Parameters<SignalingHubEvents[E]>): boolean;
244
+ emit(event: string, ...args: unknown[]): boolean;
245
+ }
246
+
247
+ export declare function createWebRTC(app: unknown, opts?: WebRTCOptions): SignalingHub;
248
+
249
+ // ---------------------------------------------------------------------------
250
+ // Join tokens
251
+ // ---------------------------------------------------------------------------
252
+
253
+ export interface SignJoinTokenOptions {
254
+ secret: string | Buffer;
255
+ user: string | { id?: string; userId?: string; sub?: string; [k: string]: unknown };
256
+ room: string;
257
+ ttl?: number;
258
+ claims?: Record<string, unknown>;
259
+ algorithm?: string;
260
+ audience?: string;
261
+ }
262
+
263
+ export interface VerifyJoinTokenOptions {
264
+ secret: string | Buffer;
265
+ room?: string;
266
+ audience?: string | string[];
267
+ algorithms?: string | string[];
268
+ clockTolerance?: number;
269
+ }
270
+
271
+ export declare function signJoinToken(opts: SignJoinTokenOptions): string;
272
+
273
+ export declare function verifyJoinToken(
274
+ token: string,
275
+ opts: VerifyJoinTokenOptions
276
+ ): { room: string; user: unknown; sub?: string; aud?: string; [k: string]: unknown };
277
+
278
+ // ---------------------------------------------------------------------------
279
+ // Observability
280
+ // ---------------------------------------------------------------------------
281
+
282
+ export interface ObservabilityBindOptions {
283
+ metrics?: unknown;
284
+ tracer?: unknown;
285
+ prefix?: string;
286
+ }
287
+
288
+ export declare function bindObservability(
289
+ hub: SignalingHub,
290
+ opts?: ObservabilityBindOptions
291
+ ): () => void;
292
+
293
+ // ---------------------------------------------------------------------------
294
+ // E2EE key relay
295
+ // ---------------------------------------------------------------------------
296
+
297
+ export interface E2eeKeyEvent {
298
+ from: string;
299
+ epoch: number;
300
+ key: Buffer;
301
+ }
302
+
303
+ export declare class E2eeChannel {
304
+ readonly peer: Peer;
305
+ readonly hub: SignalingHub;
306
+ epoch: number;
307
+ constructor(peer: Peer, hub: SignalingHub);
308
+ publish(epoch: number | null, key: Buffer | Uint8Array | string): number;
309
+ subscribe(fn: (ev: E2eeKeyEvent) => void): () => void;
310
+ }
311
+
312
+ export declare function attachE2ee(peer: Peer, hub: SignalingHub): E2eeChannel;
313
+ export declare function generateE2eeKeyPair(): { publicKey: KeyObject; privateKey: KeyObject };
314
+ export declare function sealKey(plaintext: Buffer | Uint8Array, recipientPubKey: KeyObject | Buffer): Buffer;
315
+ export declare function openSealedKey(sealed: Buffer | Uint8Array, recipientPrivKey: KeyObject | Buffer): Buffer;
316
+
317
+ // ---------------------------------------------------------------------------
318
+ // Cluster adapter
319
+ // ---------------------------------------------------------------------------
320
+
321
+ export interface ClusterAdapter {
322
+ publish(channel: string, message: unknown): void | Promise<void>;
323
+ subscribe(channel: string, handler: (message: unknown) => void): (() => void) | void;
324
+ }
325
+
326
+ export interface UseClusterOptions {
327
+ nodeId?: string;
328
+ }
329
+
330
+ export declare class ClusterCoordinator {
331
+ readonly hub: SignalingHub;
332
+ readonly adapter: ClusterAdapter;
333
+ readonly nodeId: string;
334
+ constructor(hub: SignalingHub, adapter: ClusterAdapter, opts?: UseClusterOptions);
335
+ locate(peerId: string): { nodeId: string; room: string } | null;
336
+ routeDirect(toPeerId: string, type: string, payload: object): boolean;
337
+ fanoutRoom(roomName: string, type: string, payload: object, excludeId?: string): void;
338
+ close(): void;
339
+ }
340
+
341
+ export declare function useCluster(
342
+ hub: SignalingHub,
343
+ adapter: ClusterAdapter,
344
+ opts?: UseClusterOptions
345
+ ): ClusterCoordinator;
346
+
347
+ export declare class MemoryClusterAdapter implements ClusterAdapter {
348
+ publish(channel: string, message: unknown): void;
349
+ subscribe(channel: string, handler: (message: unknown) => void): () => void;
350
+ }
351
+
352
+ // ---------------------------------------------------------------------------
353
+ // CLI
354
+ // ---------------------------------------------------------------------------
355
+
356
+ export interface WebRTCCommandDeps {
357
+ out?: (line: string) => void;
358
+ err?: (line: string) => void;
359
+ setExit?: (code: number) => void;
360
+ stunBinding?: typeof stunBinding;
361
+ }
362
+
363
+ export declare function runWebRTCCommand(
364
+ subcmd: 'stun' | 'turn-creds' | 'join-token' | 'verify-token' | 'help' | string,
365
+ flags?: Map<string, string>,
366
+ deps?: WebRTCCommandDeps
367
+ ): Promise<number>;
368
+
369
+ // ---------------------------------------------------------------------------
370
+ // SFU adapter (interface only - real implementations land in later PRs)
371
+ // ---------------------------------------------------------------------------
372
+
373
+ export interface SfuPeerInfo {
374
+ id: string;
375
+ user?: unknown;
376
+ room: string;
377
+ joinedAt: number;
378
+ }
379
+
380
+ export interface SfuRouter { id: string; routerId: string; }
381
+ export interface SfuTransport {
382
+ id: string;
383
+ transportId: string;
384
+ routerId: string;
385
+ peer: SfuPeerInfo | null;
386
+ iceParameters: unknown;
387
+ dtlsParameters: unknown;
388
+ }
389
+ export interface SfuProducer {
390
+ id: string;
391
+ producerId: string;
392
+ transportId: string;
393
+ kind: 'audio' | 'video';
394
+ rtpParams: unknown;
395
+ paused: boolean;
396
+ }
397
+ export interface SfuConsumer {
398
+ id: string;
399
+ consumerId: string;
400
+ transportId: string;
401
+ producerId: string;
402
+ kind: 'audio' | 'video';
403
+ rtpParams: unknown;
404
+ rtpCaps: unknown;
405
+ }
406
+ export interface SfuStats {
407
+ kind: 'global' | 'router' | 'transport';
408
+ [key: string]: unknown;
409
+ }
410
+
411
+ export type SfuEventHandler = (event: string, payload: unknown) => void;
412
+
413
+ export declare class SfuAdapter {
414
+ constructor();
415
+ createRouter(opts?: unknown): Promise<SfuRouter>;
416
+ createTransport(router: SfuRouter, peer: SfuPeerInfo): Promise<SfuTransport>;
417
+ produce(transport: SfuTransport, kind: 'audio' | 'video', rtpParams: unknown): Promise<SfuProducer>;
418
+ consume(transport: SfuTransport, producerId: string, rtpCaps: unknown): Promise<SfuConsumer>;
419
+ pauseProducer(producerId: string): Promise<void>;
420
+ resumeProducer(producerId: string): Promise<void>;
421
+ closeRouter(routerId: string): Promise<void>;
422
+ stats(scope?: string): Promise<SfuStats>;
423
+ onEvent(handler: SfuEventHandler): () => void;
424
+ }
425
+
426
+ export declare class MemorySfuAdapter extends SfuAdapter {
427
+ constructor(opts?: Record<string, unknown>);
428
+ }
429
+
430
+ export interface MediasoupAdapterOptions {
431
+ mediasoup?: unknown;
432
+ worker?: unknown;
433
+ workerSettings?: Record<string, unknown>;
434
+ mediaCodecs?: Array<Record<string, unknown>>;
435
+ webRtcTransportOptions?: Record<string, unknown>;
436
+ }
437
+
438
+ export declare class MediasoupSfuAdapter extends SfuAdapter {
439
+ constructor(opts?: MediasoupAdapterOptions);
440
+ close(): Promise<void>;
441
+ }
442
+
443
+ export interface LiveKitAdapterOptions {
444
+ url: string;
445
+ apiKey: string;
446
+ apiSecret: string;
447
+ livekit?: unknown;
448
+ client?: unknown;
449
+ defaultRoomOpts?: Record<string, unknown>;
450
+ defaultGrants?: Record<string, unknown>;
451
+ tokenTtl?: string | number;
452
+ }
453
+
454
+ export declare class LiveKitSfuAdapter extends SfuAdapter {
455
+ constructor(opts: LiveKitAdapterOptions);
456
+ }
457
+
458
+ export declare function loadSfuAdapter(
459
+ spec: SfuAdapter | 'memory' | 'mediasoup' | 'livekit' | string,
460
+ opts?: Record<string, unknown>,
461
+ ): SfuAdapter;
462
+
463
+ // ---------------------------------------------------------------------------
464
+ // Server-side bot peer (wrtc)
465
+ // ---------------------------------------------------------------------------
466
+
467
+ export interface BotPeerOptions {
468
+ hub: SignalingHub;
469
+ room: string;
470
+ user?: unknown;
471
+ ip?: string;
472
+ joinToken?: string;
473
+ iceServers?: Array<Record<string, unknown>>;
474
+ rtcConfig?: Record<string, unknown>;
475
+ wrtc?: unknown;
476
+ onTrack?: (track: unknown, streams: unknown[], fromPeerId: string) => void;
477
+ onDataChannel?: (channel: unknown, fromPeerId: string) => void;
478
+ onPeerJoin?: (remotePeerId: string) => void;
479
+ onPeerLeave?: (remotePeerId: string) => void;
480
+ onError?: (err: Error) => void;
481
+ }
482
+
483
+ export interface BotPeerHandle {
484
+ peer: Peer;
485
+ peerConnections: Map<string, unknown>;
486
+ getPeerConnection: (remotePeerId: string) => unknown | undefined;
487
+ ready: Promise<{ peerId: string }>;
488
+ close: () => void;
489
+ }
490
+
491
+ export declare function spawnBotPeer(opts: BotPeerOptions): BotPeerHandle;
492
+
493
+ // ---------------------------------------------------------------------------
494
+ // Errors
495
+ // ---------------------------------------------------------------------------
496
+
497
+ export declare class WebRTCError extends Error { readonly code: string; }
498
+ export declare class SignalingError extends WebRTCError {}
499
+ export declare class IceError extends WebRTCError {}
500
+ export declare class TurnError extends WebRTCError {}
501
+ export declare class SdpError extends WebRTCError {}