@zero-server/sdk 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 +54 -53
- package/index.js +116 -4
- package/lib/app.js +22 -22
- package/lib/auth/authorize.js +11 -11
- package/lib/auth/enrollment.js +5 -5
- package/lib/auth/jwt.js +9 -9
- package/lib/auth/oauth.js +1 -1
- package/lib/auth/session.js +5 -5
- package/lib/auth/trustedDevice.js +2 -2
- package/lib/auth/twoFactor.js +11 -11
- package/lib/auth/webauthn.js +6 -6
- package/lib/body/json.js +1 -1
- package/lib/body/raw.js +1 -1
- package/lib/body/rawBuffer.js +1 -1
- package/lib/body/text.js +1 -1
- package/lib/body/urlencoded.js +3 -3
- package/lib/cli.js +43 -28
- package/lib/cluster.js +3 -3
- package/lib/debug.js +10 -10
- package/lib/env/index.js +11 -11
- package/lib/errors.js +131 -16
- package/lib/fetch/index.js +1 -1
- package/lib/grpc/call.js +14 -14
- package/lib/grpc/client.js +4 -4
- package/lib/grpc/codec.js +7 -7
- package/lib/grpc/credentials.js +2 -2
- package/lib/grpc/frame.js +2 -2
- package/lib/grpc/health.js +3 -3
- package/lib/grpc/index.js +3 -3
- package/lib/grpc/metadata.js +3 -3
- package/lib/grpc/proto.js +5 -5
- package/lib/grpc/reflection.js +2 -2
- package/lib/grpc/server.js +3 -3
- package/lib/grpc/status.js +2 -2
- package/lib/grpc/watch.js +1 -1
- package/lib/http/request.js +13 -13
- package/lib/http/response.js +2 -2
- package/lib/lifecycle.js +5 -5
- package/lib/middleware/compress.js +4 -4
- package/lib/observe/health.js +1 -1
- package/lib/observe/index.js +1 -1
- package/lib/observe/logger.js +3 -3
- package/lib/observe/metrics.js +4 -4
- package/lib/observe/tracing.js +4 -4
- package/lib/orm/adapters/json.js +1 -1
- package/lib/orm/adapters/memory.js +2 -2
- package/lib/orm/adapters/mongo.js +2 -2
- package/lib/orm/adapters/mysql.js +2 -2
- package/lib/orm/adapters/postgres.js +2 -2
- package/lib/orm/adapters/sqlite.js +3 -3
- package/lib/orm/audit.js +1 -1
- package/lib/orm/index.js +7 -7
- package/lib/orm/migrate.js +1 -1
- package/lib/orm/model.js +15 -15
- package/lib/orm/procedures.js +1 -1
- package/lib/orm/profiler.js +1 -1
- package/lib/orm/query.js +9 -9
- package/lib/orm/schema.js +1 -1
- package/lib/orm/seed/data/person.js +1 -1
- package/lib/orm/seed/fake.js +10 -10
- package/lib/orm/seed/index.js +4 -4
- package/lib/orm/seed/rng.js +1 -1
- package/lib/orm/snapshot.js +3 -3
- package/lib/orm/tenancy.js +6 -6
- package/lib/orm/views.js +1 -1
- package/lib/router/index.js +9 -9
- package/lib/webrtc/bot.js +405 -0
- package/lib/webrtc/cli.js +182 -0
- package/lib/webrtc/cluster.js +338 -0
- package/lib/webrtc/e2ee.js +274 -0
- package/lib/webrtc/ice.js +363 -0
- package/lib/webrtc/index.js +212 -0
- package/lib/webrtc/joinToken.js +171 -0
- package/lib/webrtc/observe.js +260 -0
- package/lib/webrtc/peer.js +143 -0
- package/lib/webrtc/room.js +184 -0
- package/lib/webrtc/sdp.js +503 -0
- package/lib/webrtc/sfu/index.js +251 -0
- package/lib/webrtc/sfu/livekit.js +304 -0
- package/lib/webrtc/sfu/mediasoup.js +357 -0
- package/lib/webrtc/sfu/memory.js +221 -0
- package/lib/webrtc/signaling.js +590 -0
- package/lib/webrtc/stun.js +484 -0
- package/lib/webrtc/turn/codec.js +370 -0
- package/lib/webrtc/turn/credentials.js +156 -0
- package/lib/webrtc/turn/server.js +648 -0
- package/package.json +2 -2
- package/types/body.d.ts +82 -14
- package/types/cli.d.ts +40 -2
- package/types/index.d.ts +19 -6
- package/types/middleware.d.ts +18 -72
- package/types/orm.d.ts +4 -13
- package/types/request.d.ts +3 -3
- package/types/webrtc.d.ts +501 -0
package/lib/env/index.js
CHANGED
|
@@ -61,7 +61,7 @@ function parse(src)
|
|
|
61
61
|
const key = line.slice(0, eqIdx).trim();
|
|
62
62
|
let value = line.slice(eqIdx + 1).trim();
|
|
63
63
|
|
|
64
|
-
// Validate key name
|
|
64
|
+
// Validate key name - only word chars + dots
|
|
65
65
|
if (!/^[\w.]+$/.test(key)) continue;
|
|
66
66
|
|
|
67
67
|
// Quoted values
|
|
@@ -72,7 +72,7 @@ function parse(src)
|
|
|
72
72
|
}
|
|
73
73
|
else if (q === '"' || q === "'" || q === '`')
|
|
74
74
|
{
|
|
75
|
-
// Multiline
|
|
75
|
+
// Multiline - read until closing quote
|
|
76
76
|
let multiline = value.slice(1);
|
|
77
77
|
while (i < lines.length)
|
|
78
78
|
{
|
|
@@ -89,7 +89,7 @@ function parse(src)
|
|
|
89
89
|
}
|
|
90
90
|
else
|
|
91
91
|
{
|
|
92
|
-
// Unquoted
|
|
92
|
+
// Unquoted - strip inline comment
|
|
93
93
|
const hashIdx = value.indexOf(' #');
|
|
94
94
|
if (hashIdx !== -1) value = value.slice(0, hashIdx).trim();
|
|
95
95
|
}
|
|
@@ -215,10 +215,10 @@ let _loaded = false;
|
|
|
215
215
|
* Load environment variables from `.env` files and validate against a typed schema.
|
|
216
216
|
*
|
|
217
217
|
* Files are loaded in precedence order (later overrides earlier):
|
|
218
|
-
* 1. `.env`
|
|
219
|
-
* 2. `.env.local`
|
|
220
|
-
* 3. `.env.{NODE_ENV}`
|
|
221
|
-
* 4. `.env.{NODE_ENV}.local`
|
|
218
|
+
* 1. `.env` - shared defaults
|
|
219
|
+
* 2. `.env.local` - local overrides (gitignored)
|
|
220
|
+
* 3. `.env.{NODE_ENV}` - environment-specific (e.g. `.env.production`)
|
|
221
|
+
* 4. `.env.{NODE_ENV}.local` - env-specific local overrides
|
|
222
222
|
*
|
|
223
223
|
* Process environment variables (`process.env`) always take precedence.
|
|
224
224
|
*
|
|
@@ -284,7 +284,7 @@ function load(schema, options = {})
|
|
|
284
284
|
}
|
|
285
285
|
else
|
|
286
286
|
{
|
|
287
|
-
// No schema
|
|
287
|
+
// No schema - load everything
|
|
288
288
|
Object.assign(merged, raw);
|
|
289
289
|
for (const key of Object.keys(raw))
|
|
290
290
|
{
|
|
@@ -340,7 +340,7 @@ function load(schema, options = {})
|
|
|
340
340
|
}
|
|
341
341
|
else
|
|
342
342
|
{
|
|
343
|
-
// No schema
|
|
343
|
+
// No schema - store raw strings
|
|
344
344
|
Object.assign(_store, merged);
|
|
345
345
|
}
|
|
346
346
|
|
|
@@ -427,11 +427,11 @@ function reset()
|
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
// ===========================================================
|
|
430
|
-
// Proxy-based accessor
|
|
430
|
+
// Proxy-based accessor - env.PORT, env('PORT'), env.get('PORT')
|
|
431
431
|
// ===========================================================
|
|
432
432
|
|
|
433
433
|
/**
|
|
434
|
-
* The env function
|
|
434
|
+
* The env function - callable as `env(key)` or `env.key`.
|
|
435
435
|
*
|
|
436
436
|
* @param {string} key - Environment variable name.
|
|
437
437
|
* @returns {*} Result value.
|
package/lib/errors.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* age: 'must be >= 18',
|
|
22
22
|
* });
|
|
23
23
|
*
|
|
24
|
-
* // Factory
|
|
24
|
+
* // Factory - create by status code
|
|
25
25
|
* throw createError(503, 'Try again later');
|
|
26
26
|
*/
|
|
27
27
|
|
|
@@ -288,7 +288,7 @@ class ServiceUnavailableError extends HttpError
|
|
|
288
288
|
// --- Framework Error Classes -------------------------------------
|
|
289
289
|
|
|
290
290
|
/**
|
|
291
|
-
* Database / ORM error
|
|
291
|
+
* Database / ORM error - wraps adapter-level failures.
|
|
292
292
|
*/
|
|
293
293
|
class DatabaseError extends HttpError
|
|
294
294
|
{
|
|
@@ -308,7 +308,7 @@ class DatabaseError extends HttpError
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
/**
|
|
311
|
-
* Configuration error
|
|
311
|
+
* Configuration error - thrown when app/adapter configuration is invalid.
|
|
312
312
|
*/
|
|
313
313
|
class ConfigurationError extends HttpError
|
|
314
314
|
{
|
|
@@ -326,7 +326,7 @@ class ConfigurationError extends HttpError
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
/**
|
|
329
|
-
* Middleware error
|
|
329
|
+
* Middleware error - a middleware function failed unexpectedly.
|
|
330
330
|
*/
|
|
331
331
|
class MiddlewareError extends HttpError
|
|
332
332
|
{
|
|
@@ -344,7 +344,7 @@ class MiddlewareError extends HttpError
|
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
/**
|
|
347
|
-
* Routing error
|
|
347
|
+
* Routing error - thrown when route resolution fails.
|
|
348
348
|
*/
|
|
349
349
|
class RoutingError extends HttpError
|
|
350
350
|
{
|
|
@@ -364,7 +364,7 @@ class RoutingError extends HttpError
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
/**
|
|
367
|
-
* Timeout error
|
|
367
|
+
* Timeout error - operation exceeded allowed time.
|
|
368
368
|
*/
|
|
369
369
|
class TimeoutError extends HttpError
|
|
370
370
|
{
|
|
@@ -384,7 +384,7 @@ class TimeoutError extends HttpError
|
|
|
384
384
|
// --- ORM-Specific Error Classes ----------------------------------
|
|
385
385
|
|
|
386
386
|
/**
|
|
387
|
-
* Connection error
|
|
387
|
+
* Connection error - database connection failures with retry context.
|
|
388
388
|
*/
|
|
389
389
|
class ConnectionError extends DatabaseError
|
|
390
390
|
{
|
|
@@ -409,7 +409,7 @@ class ConnectionError extends DatabaseError
|
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
/**
|
|
412
|
-
* Migration error
|
|
412
|
+
* Migration error - migration execution failures.
|
|
413
413
|
*/
|
|
414
414
|
class MigrationError extends DatabaseError
|
|
415
415
|
{
|
|
@@ -431,7 +431,7 @@ class MigrationError extends DatabaseError
|
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
/**
|
|
434
|
-
* Transaction error
|
|
434
|
+
* Transaction error - transaction commit/rollback failures.
|
|
435
435
|
*/
|
|
436
436
|
class TransactionError extends DatabaseError
|
|
437
437
|
{
|
|
@@ -449,7 +449,7 @@ class TransactionError extends DatabaseError
|
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
/**
|
|
452
|
-
* Query error
|
|
452
|
+
* Query error - query execution failures with SQL context.
|
|
453
453
|
*/
|
|
454
454
|
class QueryError extends DatabaseError
|
|
455
455
|
{
|
|
@@ -471,7 +471,7 @@ class QueryError extends DatabaseError
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
/**
|
|
474
|
-
* Adapter error
|
|
474
|
+
* Adapter error - adapter-level issues (driver not found, unsupported operation).
|
|
475
475
|
*/
|
|
476
476
|
class AdapterError extends DatabaseError
|
|
477
477
|
{
|
|
@@ -490,7 +490,7 @@ class AdapterError extends DatabaseError
|
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
/**
|
|
493
|
-
* Cache error
|
|
493
|
+
* Cache error - caching layer failures.
|
|
494
494
|
*/
|
|
495
495
|
class CacheError extends HttpError
|
|
496
496
|
{
|
|
@@ -512,7 +512,7 @@ class CacheError extends HttpError
|
|
|
512
512
|
// --- Phase 4 Error Classes ---------------------------------------
|
|
513
513
|
|
|
514
514
|
/**
|
|
515
|
-
* Tenancy error
|
|
515
|
+
* Tenancy error - multi-tenancy operation failures.
|
|
516
516
|
*/
|
|
517
517
|
class TenancyError extends DatabaseError
|
|
518
518
|
{
|
|
@@ -532,7 +532,7 @@ class TenancyError extends DatabaseError
|
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
/**
|
|
535
|
-
* Audit error
|
|
535
|
+
* Audit error - audit logging failures.
|
|
536
536
|
*/
|
|
537
537
|
class AuditError extends DatabaseError
|
|
538
538
|
{
|
|
@@ -552,7 +552,7 @@ class AuditError extends DatabaseError
|
|
|
552
552
|
}
|
|
553
553
|
|
|
554
554
|
/**
|
|
555
|
-
* Plugin error
|
|
555
|
+
* Plugin error - plugin registration or lifecycle failures.
|
|
556
556
|
*/
|
|
557
557
|
class PluginError extends HttpError
|
|
558
558
|
{
|
|
@@ -571,8 +571,117 @@ class PluginError extends HttpError
|
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
+
// --- WebRTC Error Classes ----------------------------------------
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Base WebRTC error. All `@zero-server/webrtc` errors extend this so
|
|
578
|
+
* they round-trip through `errorHandler` like every other framework error.
|
|
579
|
+
*
|
|
580
|
+
* @section WebRTC Error Classes
|
|
581
|
+
*/
|
|
582
|
+
class WebRTCError extends HttpError
|
|
583
|
+
{
|
|
584
|
+
/**
|
|
585
|
+
* @constructor
|
|
586
|
+
* @param {string} [message] - Description.
|
|
587
|
+
* @param {object} [opts] - Additional error options.
|
|
588
|
+
* @param {number} [opts.statusCode=500] - HTTP status override.
|
|
589
|
+
* @param {string} [opts.code='WEBRTC_ERROR'] - Machine-readable code.
|
|
590
|
+
* @param {*} [opts.details] - Extra context.
|
|
591
|
+
*/
|
|
592
|
+
constructor(message, opts = {})
|
|
593
|
+
{
|
|
594
|
+
super(opts.statusCode || 500, message || 'WebRTC Error', { code: 'WEBRTC_ERROR', ...opts });
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Signaling error - malformed or rejected signaling message
|
|
600
|
+
* (offer / answer / ice / mute / e2ee-key / bye).
|
|
601
|
+
*
|
|
602
|
+
* @section WebRTC Error Classes
|
|
603
|
+
*/
|
|
604
|
+
class SignalingError extends WebRTCError
|
|
605
|
+
{
|
|
606
|
+
/**
|
|
607
|
+
* @constructor
|
|
608
|
+
* @param {string} [message] - Description.
|
|
609
|
+
* @param {object} [opts] - Additional options.
|
|
610
|
+
* @param {string} [opts.type] - Signaling message type that failed.
|
|
611
|
+
* @param {string} [opts.peer] - Peer id involved (if known).
|
|
612
|
+
*/
|
|
613
|
+
constructor(message, opts = {})
|
|
614
|
+
{
|
|
615
|
+
super(message || 'Signaling Error', { statusCode: 400, code: 'SIGNALING_ERROR', ...opts });
|
|
616
|
+
if (opts.type) this.type = opts.type;
|
|
617
|
+
if (opts.peer) this.peer = opts.peer;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* ICE error - candidate parsing, filtering, or selection failure.
|
|
623
|
+
*
|
|
624
|
+
* @section WebRTC Error Classes
|
|
625
|
+
*/
|
|
626
|
+
class IceError extends WebRTCError
|
|
627
|
+
{
|
|
628
|
+
/**
|
|
629
|
+
* @constructor
|
|
630
|
+
* @param {string} [message] - Description.
|
|
631
|
+
* @param {object} [opts] - Additional options.
|
|
632
|
+
* @param {string} [opts.candidate] - Raw candidate line (if available).
|
|
633
|
+
*/
|
|
634
|
+
constructor(message, opts = {})
|
|
635
|
+
{
|
|
636
|
+
super(message || 'ICE Error', { statusCode: 400, code: 'ICE_ERROR', ...opts });
|
|
637
|
+
if (opts.candidate) this.candidate = opts.candidate;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* TURN error - upstream TURN server / credential issuance failure.
|
|
643
|
+
*
|
|
644
|
+
* @section WebRTC Error Classes
|
|
645
|
+
*/
|
|
646
|
+
class TurnError extends WebRTCError
|
|
647
|
+
{
|
|
648
|
+
/**
|
|
649
|
+
* @constructor
|
|
650
|
+
* @param {string} [message] - Description.
|
|
651
|
+
* @param {object} [opts] - Additional options.
|
|
652
|
+
* @param {string} [opts.realm] - TURN realm (if applicable).
|
|
653
|
+
* @param {string} [opts.username] - Username that failed (if applicable).
|
|
654
|
+
*/
|
|
655
|
+
constructor(message, opts = {})
|
|
656
|
+
{
|
|
657
|
+
super(message || 'TURN Error', { statusCode: 502, code: 'TURN_ERROR', ...opts });
|
|
658
|
+
if (opts.realm) this.realm = opts.realm;
|
|
659
|
+
if (opts.username) this.username = opts.username;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* SDP error - malformed or policy-rejected Session Description Protocol payload.
|
|
665
|
+
*
|
|
666
|
+
* @section WebRTC Error Classes
|
|
667
|
+
*/
|
|
668
|
+
class SdpError extends WebRTCError
|
|
669
|
+
{
|
|
670
|
+
/**
|
|
671
|
+
* @constructor
|
|
672
|
+
* @param {string} [message] - Description.
|
|
673
|
+
* @param {object} [opts] - Additional options.
|
|
674
|
+
* @param {number} [opts.line] - Line number where parsing failed.
|
|
675
|
+
*/
|
|
676
|
+
constructor(message, opts = {})
|
|
677
|
+
{
|
|
678
|
+
super(message || 'SDP Error', { statusCode: 400, code: 'SDP_ERROR', ...opts });
|
|
679
|
+
if (opts.line !== undefined) this.line = opts.line;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
574
683
|
/**
|
|
575
|
-
* Procedure error
|
|
684
|
+
* Procedure error - stored procedure/function failures.
|
|
576
685
|
*/
|
|
577
686
|
class ProcedureError extends DatabaseError
|
|
578
687
|
{
|
|
@@ -678,6 +787,12 @@ module.exports = {
|
|
|
678
787
|
AuditError,
|
|
679
788
|
PluginError,
|
|
680
789
|
ProcedureError,
|
|
790
|
+
// WebRTC errors
|
|
791
|
+
WebRTCError,
|
|
792
|
+
SignalingError,
|
|
793
|
+
IceError,
|
|
794
|
+
TurnError,
|
|
795
|
+
SdpError,
|
|
681
796
|
createError,
|
|
682
797
|
isHttpError,
|
|
683
798
|
};
|
package/lib/fetch/index.js
CHANGED
|
@@ -23,7 +23,7 @@ const STATUS_CODES = http.STATUS_CODES;
|
|
|
23
23
|
* @param {import('http').Agent} [opts.agent] - Custom HTTP agent.
|
|
24
24
|
* @param {Function} [opts.onDownloadProgress] - `({ loaded, total }) => void` download progress callback.
|
|
25
25
|
* @param {Function} [opts.onUploadProgress] - `({ loaded, total }) => void` upload progress callback.
|
|
26
|
-
* @param {boolean} [opts.rejectUnauthorized] - Reject connections with unverified certs (default: Node default `true`). TLS option
|
|
26
|
+
* @param {boolean} [opts.rejectUnauthorized] - Reject connections with unverified certs (default: Node default `true`). TLS option - passed to `https.request()`.
|
|
27
27
|
* @param {string|Buffer|Array} [opts.ca] - Override default CA certificates.
|
|
28
28
|
* @param {string|Buffer} [opts.cert] - Client certificate (PEM) for mutual TLS.
|
|
29
29
|
* @param {string|Buffer} [opts.key] - Private key (PEM) for mutual TLS.
|
package/lib/grpc/call.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Wraps HTTP/2 streams with protobuf encode/decode, metadata,
|
|
5
5
|
* framing, deadline enforcement, and cancellation support.
|
|
6
6
|
*
|
|
7
|
-
* - `UnaryCall`
|
|
8
|
-
* - `ServerStreamCall`
|
|
9
|
-
* - `ClientStreamCall`
|
|
10
|
-
* - `BidiStreamCall`
|
|
7
|
+
* - `UnaryCall` - single request, single response
|
|
8
|
+
* - `ServerStreamCall` - single request, stream of responses
|
|
9
|
+
* - `ClientStreamCall` - stream of requests, single response
|
|
10
|
+
* - `BidiStreamCall` - bidirectional streaming
|
|
11
11
|
*
|
|
12
12
|
* @example | Unary handler
|
|
13
13
|
* async function GetUser(call) {
|
|
@@ -181,7 +181,7 @@ class BaseCall extends EventEmitter
|
|
|
181
181
|
|
|
182
182
|
if (!this._headersSent)
|
|
183
183
|
{
|
|
184
|
-
// Trailers-Only response
|
|
184
|
+
// Trailers-Only response - include status in initial HEADERS frame
|
|
185
185
|
this._headersSent = true;
|
|
186
186
|
try
|
|
187
187
|
{
|
|
@@ -199,7 +199,7 @@ class BaseCall extends EventEmitter
|
|
|
199
199
|
}
|
|
200
200
|
else
|
|
201
201
|
{
|
|
202
|
-
// Headers already sent
|
|
202
|
+
// Headers already sent - send trailing HEADERS after final DATA
|
|
203
203
|
this.stream.on('wantTrailers', () =>
|
|
204
204
|
{
|
|
205
205
|
try { this.stream.sendTrailers(trailHeaders); }
|
|
@@ -359,7 +359,7 @@ class BaseCall extends EventEmitter
|
|
|
359
359
|
// -- Unary Call --------------------------------------------
|
|
360
360
|
|
|
361
361
|
/**
|
|
362
|
-
* A unary gRPC call
|
|
362
|
+
* A unary gRPC call - single request message, single response message.
|
|
363
363
|
*
|
|
364
364
|
* @class
|
|
365
365
|
* @extends BaseCall
|
|
@@ -391,7 +391,7 @@ class UnaryCall extends BaseCall
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
/**
|
|
394
|
-
* Initialize the call
|
|
394
|
+
* Initialize the call - collect the full request body and decode it.
|
|
395
395
|
* @private
|
|
396
396
|
* @returns {Promise<void>}
|
|
397
397
|
*/
|
|
@@ -422,7 +422,7 @@ class UnaryCall extends BaseCall
|
|
|
422
422
|
// -- Server Streaming Call ---------------------------------
|
|
423
423
|
|
|
424
424
|
/**
|
|
425
|
-
* A server-streaming gRPC call
|
|
425
|
+
* A server-streaming gRPC call - single request, multiple responses.
|
|
426
426
|
* The handler calls `call.write(msg)` for each response and `call.end()` to finish.
|
|
427
427
|
*
|
|
428
428
|
* @class
|
|
@@ -481,7 +481,7 @@ class ServerStreamCall extends BaseCall
|
|
|
481
481
|
// -- Client Streaming Call ---------------------------------
|
|
482
482
|
|
|
483
483
|
/**
|
|
484
|
-
* A client-streaming gRPC call
|
|
484
|
+
* A client-streaming gRPC call - multiple requests, single response.
|
|
485
485
|
* The handler iterates `for await (const msg of call)` to consume messages,
|
|
486
486
|
* then returns the response object.
|
|
487
487
|
*
|
|
@@ -512,7 +512,7 @@ class ClientStreamCall extends BaseCall
|
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
/**
|
|
515
|
-
* Initialize
|
|
515
|
+
* Initialize - set up the frame parser to enqueue decoded messages.
|
|
516
516
|
* @private
|
|
517
517
|
*/
|
|
518
518
|
_init()
|
|
@@ -560,7 +560,7 @@ class ClientStreamCall extends BaseCall
|
|
|
560
560
|
}
|
|
561
561
|
|
|
562
562
|
/**
|
|
563
|
-
* Async iterator
|
|
563
|
+
* Async iterator - enables `for await (const msg of call)`.
|
|
564
564
|
*
|
|
565
565
|
* @returns {AsyncIterator<object>}
|
|
566
566
|
*/
|
|
@@ -589,7 +589,7 @@ class ClientStreamCall extends BaseCall
|
|
|
589
589
|
// -- Bidirectional Streaming Call ---------------------------
|
|
590
590
|
|
|
591
591
|
/**
|
|
592
|
-
* A bidirectional streaming gRPC call
|
|
592
|
+
* A bidirectional streaming gRPC call - multiple requests AND multiple responses.
|
|
593
593
|
* The handler can `for await` incoming messages while simultaneously
|
|
594
594
|
* calling `call.write()` to send responses.
|
|
595
595
|
*
|
|
@@ -673,7 +673,7 @@ class BidiStreamCall extends BaseCall
|
|
|
673
673
|
}
|
|
674
674
|
|
|
675
675
|
/**
|
|
676
|
-
* Async iterator
|
|
676
|
+
* Async iterator - enables `for await (const msg of call)`.
|
|
677
677
|
*
|
|
678
678
|
* @returns {AsyncIterator<object>}
|
|
679
679
|
*/
|
package/lib/grpc/client.js
CHANGED
|
@@ -266,7 +266,7 @@ class GrpcClient extends EventEmitter
|
|
|
266
266
|
// -- Unary Call -----------------------------------------
|
|
267
267
|
|
|
268
268
|
/**
|
|
269
|
-
* Make a unary gRPC call
|
|
269
|
+
* Make a unary gRPC call - send one message, receive one response.
|
|
270
270
|
*
|
|
271
271
|
* @param {string} methodName - RPC method name as defined in the proto service.
|
|
272
272
|
* @param {object} request - Request message object.
|
|
@@ -394,7 +394,7 @@ class GrpcClient extends EventEmitter
|
|
|
394
394
|
// -- Server Streaming ----------------------------------
|
|
395
395
|
|
|
396
396
|
/**
|
|
397
|
-
* Make a server-streaming gRPC call
|
|
397
|
+
* Make a server-streaming gRPC call - send one request, receive a stream of responses.
|
|
398
398
|
* Returns an async-iterable that yields decoded response messages.
|
|
399
399
|
*
|
|
400
400
|
* @param {string} methodName - RPC method name.
|
|
@@ -509,7 +509,7 @@ class GrpcClient extends EventEmitter
|
|
|
509
509
|
// -- Client Streaming ----------------------------------
|
|
510
510
|
|
|
511
511
|
/**
|
|
512
|
-
* Make a client-streaming gRPC call
|
|
512
|
+
* Make a client-streaming gRPC call - send a stream of requests, receive one response.
|
|
513
513
|
* Returns a writable object with `write()`, `end()`, and a `response` Promise.
|
|
514
514
|
*
|
|
515
515
|
* @param {string} methodName - RPC method name.
|
|
@@ -608,7 +608,7 @@ class GrpcClient extends EventEmitter
|
|
|
608
608
|
// -- Bidirectional Streaming ----------------------------
|
|
609
609
|
|
|
610
610
|
/**
|
|
611
|
-
* Make a bidirectional streaming gRPC call
|
|
611
|
+
* Make a bidirectional streaming gRPC call - send and receive streams simultaneously.
|
|
612
612
|
* Returns an object that is both writable (`write`/`end`) and async-iterable.
|
|
613
613
|
*
|
|
614
614
|
* @param {string} methodName - RPC method name.
|
package/lib/grpc/codec.js
CHANGED
|
@@ -76,7 +76,7 @@ const TYPE_INFO = {
|
|
|
76
76
|
// -- Writer ------------------------------------------------
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Protobuf binary writer
|
|
79
|
+
* Protobuf binary writer - encodes JavaScript objects into wire-format bytes.
|
|
80
80
|
*
|
|
81
81
|
* @class
|
|
82
82
|
*
|
|
@@ -397,7 +397,7 @@ class Writer
|
|
|
397
397
|
// -- Reader ------------------------------------------------
|
|
398
398
|
|
|
399
399
|
/**
|
|
400
|
-
* Protobuf binary reader
|
|
400
|
+
* Protobuf binary reader - decodes wire-format bytes into JavaScript values.
|
|
401
401
|
*
|
|
402
402
|
* @class
|
|
403
403
|
*
|
|
@@ -762,7 +762,7 @@ class Reader
|
|
|
762
762
|
function encode(obj, messageDesc, allMessages, depth = 0)
|
|
763
763
|
{
|
|
764
764
|
if (depth > MAX_RECURSION_DEPTH)
|
|
765
|
-
throw new Error(`Maximum encoding depth (${MAX_RECURSION_DEPTH}) exceeded
|
|
765
|
+
throw new Error(`Maximum encoding depth (${MAX_RECURSION_DEPTH}) exceeded - possible circular reference`);
|
|
766
766
|
|
|
767
767
|
if (!obj || typeof obj !== 'object')
|
|
768
768
|
return Buffer.alloc(0);
|
|
@@ -809,7 +809,7 @@ function encode(obj, messageDesc, allMessages, depth = 0)
|
|
|
809
809
|
function decode(buffer, messageDesc, allMessages, depth = 0)
|
|
810
810
|
{
|
|
811
811
|
if (depth > MAX_RECURSION_DEPTH)
|
|
812
|
-
throw new Error(`Maximum decoding depth (${MAX_RECURSION_DEPTH}) exceeded
|
|
812
|
+
throw new Error(`Maximum decoding depth (${MAX_RECURSION_DEPTH}) exceeded - possible circular reference`);
|
|
813
813
|
|
|
814
814
|
if (!Buffer.isBuffer(buffer) || buffer.length === 0)
|
|
815
815
|
return _defaultObject(messageDesc);
|
|
@@ -830,7 +830,7 @@ function decode(buffer, messageDesc, allMessages, depth = 0)
|
|
|
830
830
|
|
|
831
831
|
if (!field)
|
|
832
832
|
{
|
|
833
|
-
// Unknown field
|
|
833
|
+
// Unknown field - skip it (forward compatibility)
|
|
834
834
|
reader.skipField(wireType);
|
|
835
835
|
continue;
|
|
836
836
|
}
|
|
@@ -868,7 +868,7 @@ function _encodeField(writer, field, value, allMessages, depth)
|
|
|
868
868
|
|
|
869
869
|
if (typeInfo)
|
|
870
870
|
{
|
|
871
|
-
// Scalar type
|
|
871
|
+
// Scalar type - skip default values in proto3
|
|
872
872
|
if (_isDefaultValue(field.type, value)) return;
|
|
873
873
|
|
|
874
874
|
writer.writeTag(field.number, typeInfo.wire);
|
|
@@ -913,7 +913,7 @@ function _encodeRepeated(writer, field, values, allMessages, depth)
|
|
|
913
913
|
}
|
|
914
914
|
else
|
|
915
915
|
{
|
|
916
|
-
// Non-packable (strings, bytes, messages)
|
|
916
|
+
// Non-packable (strings, bytes, messages) - one tag per element
|
|
917
917
|
for (const v of values) _encodeField(writer, field, v, allMessages, depth);
|
|
918
918
|
}
|
|
919
919
|
}
|
package/lib/grpc/credentials.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and metadata-based credentials. Supports certificate rotation
|
|
6
6
|
* and credential composition.
|
|
7
7
|
*
|
|
8
|
-
* Uses only Node.js built-in `tls` and `fs`
|
|
8
|
+
* Uses only Node.js built-in `tls` and `fs` - no external packages.
|
|
9
9
|
*
|
|
10
10
|
* @example | Insecure (plaintext)
|
|
11
11
|
* const { ChannelCredentials, GrpcClient } = require('@zero-server/sdk');
|
|
@@ -71,7 +71,7 @@ class ChannelCredentials
|
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Create insecure (plaintext) credentials.
|
|
74
|
-
* No TLS
|
|
74
|
+
* No TLS - suitable for development or service-mesh environments
|
|
75
75
|
* where transport security is handled by the infrastructure.
|
|
76
76
|
*
|
|
77
77
|
* @returns {ChannelCredentials}
|
package/lib/grpc/frame.js
CHANGED
|
@@ -23,7 +23,7 @@ const log = require('../debug')('zero:grpc');
|
|
|
23
23
|
const FRAME_HEADER_SIZE = 5;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Maximum frame size (16 MB
|
|
26
|
+
* Maximum frame size (16 MB - matches the default gRPC max).
|
|
27
27
|
* @type {number}
|
|
28
28
|
*/
|
|
29
29
|
const MAX_FRAME_SIZE = 16 * 1024 * 1024;
|
|
@@ -92,7 +92,7 @@ function _buildFrame(payload, flag)
|
|
|
92
92
|
// -- Frame Decoder -----------------------------------------
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* Stateful gRPC frame parser
|
|
95
|
+
* Stateful gRPC frame parser - buffers incoming data and emits complete
|
|
96
96
|
* decompressed messages. Designed to be fed chunks from an HTTP/2 stream.
|
|
97
97
|
*
|
|
98
98
|
* @class
|
package/lib/grpc/health.js
CHANGED
|
@@ -193,7 +193,7 @@ class HealthService
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/**
|
|
196
|
-
* Handle a Check RPC
|
|
196
|
+
* Handle a Check RPC - unary request for current health of a service.
|
|
197
197
|
* @param {import('./call').UnaryCall} call
|
|
198
198
|
*/
|
|
199
199
|
Check(call)
|
|
@@ -205,7 +205,7 @@ class HealthService
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
/**
|
|
208
|
-
* Handle a Watch RPC
|
|
208
|
+
* Handle a Watch RPC - server-stream that pushes status changes.
|
|
209
209
|
* Sends the current status immediately, then pushes on every change.
|
|
210
210
|
* @param {import('./call').ServerStreamCall} call
|
|
211
211
|
*/
|
|
@@ -232,7 +232,7 @@ class HealthService
|
|
|
232
232
|
|
|
233
233
|
/**
|
|
234
234
|
* Get the schema object needed for server registration.
|
|
235
|
-
* Avoids requiring proto parsing
|
|
235
|
+
* Avoids requiring proto parsing - returns descriptors directly.
|
|
236
236
|
* @returns {object} Schema compatible with GrpcServiceRegistry.addService
|
|
237
237
|
*/
|
|
238
238
|
getSchema()
|
package/lib/grpc/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module grpc
|
|
3
|
-
* @description Full gRPC support for zero-server
|
|
3
|
+
* @description Full gRPC support for zero-server - zero external dependencies.
|
|
4
4
|
* Provides a proto3 parser, protobuf codec, gRPC framing, call objects,
|
|
5
5
|
* a service server, and a client for all four RPC patterns.
|
|
6
6
|
*
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - Graceful shutdown with call draining
|
|
15
15
|
* - Message size limits and deadline enforcement
|
|
16
16
|
*
|
|
17
|
-
* @example | Quick Start
|
|
17
|
+
* @example | Quick Start - Server
|
|
18
18
|
* const { createApp, parseProto } = require('@zero-server/sdk');
|
|
19
19
|
* const app = createApp();
|
|
20
20
|
* const schema = parseProto(`
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
*
|
|
36
36
|
* app.listen(50051, { http2: true });
|
|
37
37
|
*
|
|
38
|
-
* @example | Quick Start
|
|
38
|
+
* @example | Quick Start - Client
|
|
39
39
|
* const { GrpcClient, parseProto } = require('@zero-server/sdk');
|
|
40
40
|
* const schema = parseProto(fs.readFileSync('hello.proto', 'utf8'));
|
|
41
41
|
* const client = new GrpcClient('http://localhost:50051', schema, 'Greeter');
|
package/lib/grpc/metadata.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module grpc/metadata
|
|
3
|
-
* @description gRPC metadata container
|
|
3
|
+
* @description gRPC metadata container - typed key-value pairs transmitted as
|
|
4
4
|
* HTTP/2 headers (initial metadata) and trailers (trailing metadata).
|
|
5
5
|
* Keys ending in `-bin` carry binary values (base64-encoded on the wire).
|
|
6
6
|
* All other keys carry ASCII string values.
|
|
@@ -44,7 +44,7 @@ const GRPC_INTERNAL = new Set([
|
|
|
44
44
|
const MAX_KEY_LENGTH = 256;
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Maximum total metadata size in bytes (soft limit
|
|
47
|
+
* Maximum total metadata size in bytes (soft limit - 8 KB default, configurable).
|
|
48
48
|
* @type {number}
|
|
49
49
|
*/
|
|
50
50
|
const DEFAULT_MAX_METADATA_SIZE = 8192;
|
|
@@ -52,7 +52,7 @@ const DEFAULT_MAX_METADATA_SIZE = 8192;
|
|
|
52
52
|
// -- Metadata Class ----------------------------------------
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* gRPC metadata container
|
|
55
|
+
* gRPC metadata container - type-safe key-value pairs for headers and trailers.
|
|
56
56
|
*
|
|
57
57
|
* @class
|
|
58
58
|
*
|