@query-farm/vgi-rpc 0.3.4 → 0.4.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.
Files changed (50) hide show
  1. package/dist/auth.d.ts +13 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/client/connect.d.ts.map +1 -1
  4. package/dist/client/index.d.ts +2 -0
  5. package/dist/client/index.d.ts.map +1 -1
  6. package/dist/client/introspect.d.ts +1 -0
  7. package/dist/client/introspect.d.ts.map +1 -1
  8. package/dist/client/oauth.d.ts +26 -0
  9. package/dist/client/oauth.d.ts.map +1 -0
  10. package/dist/client/stream.d.ts +2 -0
  11. package/dist/client/stream.d.ts.map +1 -1
  12. package/dist/client/types.d.ts +2 -0
  13. package/dist/client/types.d.ts.map +1 -1
  14. package/dist/dispatch/stream.d.ts.map +1 -1
  15. package/dist/http/auth.d.ts +21 -0
  16. package/dist/http/auth.d.ts.map +1 -0
  17. package/dist/http/dispatch.d.ts +2 -0
  18. package/dist/http/dispatch.d.ts.map +1 -1
  19. package/dist/http/handler.d.ts.map +1 -1
  20. package/dist/http/index.d.ts +4 -0
  21. package/dist/http/index.d.ts.map +1 -1
  22. package/dist/http/jwt.d.ts +21 -0
  23. package/dist/http/jwt.d.ts.map +1 -0
  24. package/dist/http/types.d.ts +5 -0
  25. package/dist/http/types.d.ts.map +1 -1
  26. package/dist/index.d.ts +3 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1416 -46
  29. package/dist/index.js.map +18 -13
  30. package/dist/types.d.ts +8 -2
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/wire/response.d.ts.map +1 -1
  33. package/package.json +3 -2
  34. package/src/auth.ts +31 -0
  35. package/src/client/connect.ts +15 -1
  36. package/src/client/index.ts +2 -0
  37. package/src/client/introspect.ts +14 -2
  38. package/src/client/oauth.ts +74 -0
  39. package/src/client/stream.ts +12 -0
  40. package/src/client/types.ts +2 -0
  41. package/src/dispatch/stream.ts +11 -3
  42. package/src/http/auth.ts +47 -0
  43. package/src/http/dispatch.ts +6 -4
  44. package/src/http/handler.ts +41 -1
  45. package/src/http/index.ts +4 -0
  46. package/src/http/jwt.ts +66 -0
  47. package/src/http/types.ts +6 -0
  48. package/src/index.ts +7 -0
  49. package/src/types.ts +17 -3
  50. package/src/wire/response.ts +28 -14
package/src/http/types.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  // © Copyright 2025-2026, Query.Farm LLC - https://query.farm
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import type { AuthenticateFn, OAuthResourceMetadata } from "./auth.js";
5
+
4
6
  /** Configuration options for createHttpHandler(). */
5
7
  export interface HttpHandlerOptions {
6
8
  /** URL path prefix for all endpoints. Default: "/vgi" */
@@ -22,6 +24,10 @@ export interface HttpHandlerOptions {
22
24
  /** zstd compression level for responses (1-22). If set, responses are
23
25
  * compressed when the client sends Accept-Encoding: zstd. */
24
26
  compressionLevel?: number;
27
+ /** Optional authentication callback. Called for each request before dispatch. */
28
+ authenticate?: AuthenticateFn;
29
+ /** Optional RFC 9728 OAuth Protected Resource Metadata. Served at well-known endpoint. */
30
+ oauthResourceMetadata?: OAuthResourceMetadata;
25
31
  }
26
32
 
27
33
  /** Serializer for stream state objects stored in state tokens. */
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  // © Copyright 2025-2026, Query.Farm LLC - https://query.farm
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ export { AuthContext } from "./auth.js";
4
5
  export * from "./client/index.js";
5
6
  export {
6
7
  DESCRIBE_METHOD_NAME,
@@ -20,9 +21,14 @@ export {
20
21
  export { RpcError, VersionError } from "./errors.js";
21
22
  export {
22
23
  ARROW_CONTENT_TYPE,
24
+ type AuthenticateFn,
23
25
  createHttpHandler,
24
26
  type HttpHandlerOptions,
27
+ type JwtAuthenticateOptions,
25
28
  jsonStateSerializer,
29
+ jwtAuthenticate,
30
+ type OAuthResourceMetadata,
31
+ oauthResourceMetadataToJson,
26
32
  type StateSerializer,
27
33
  type UnpackedToken,
28
34
  unpackStateToken,
@@ -42,6 +48,7 @@ export {
42
48
  } from "./schema.js";
43
49
  export { VgiRpcServer } from "./server.js";
44
50
  export {
51
+ type CallContext,
45
52
  type ExchangeFn,
46
53
  type ExchangeInit,
47
54
  type HeaderInit,
package/src/types.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { RecordBatch, recordBatchFromArrays, type Schema } from "@query-farm/apache-arrow";
5
+ import { AuthContext } from "./auth.js";
5
6
  import { buildLogBatch, coerceInt64 } from "./wire/response.js";
6
7
 
7
8
  export enum MethodType {
@@ -14,6 +15,11 @@ export interface LogContext {
14
15
  clientLog(level: string, message: string, extra?: Record<string, string>): void;
15
16
  }
16
17
 
18
+ /** Extended context with authentication info, available to handlers. */
19
+ export interface CallContext extends LogContext {
20
+ readonly auth: AuthContext;
21
+ }
22
+
17
23
  /** Handler for unary (request-response) RPC methods. */
18
24
  export type UnaryHandler = (
19
25
  params: Record<string, any>,
@@ -61,7 +67,7 @@ export interface EmittedBatch {
61
67
  * Accumulates output batches during a produce/exchange call.
62
68
  * Enforces that exactly one data batch is emitted per call (plus any number of log batches).
63
69
  */
64
- export class OutputCollector implements LogContext {
70
+ export class OutputCollector implements CallContext {
65
71
  private _batches: EmittedBatch[] = [];
66
72
  private _dataBatchIdx: number | null = null;
67
73
  private _finished = false;
@@ -69,12 +75,20 @@ export class OutputCollector implements LogContext {
69
75
  private _outputSchema: Schema;
70
76
  private _serverId: string;
71
77
  private _requestId: string | null;
72
-
73
- constructor(outputSchema: Schema, producerMode = true, serverId = "", requestId: string | null = null) {
78
+ readonly auth: AuthContext;
79
+
80
+ constructor(
81
+ outputSchema: Schema,
82
+ producerMode = true,
83
+ serverId = "",
84
+ requestId: string | null = null,
85
+ authContext?: AuthContext,
86
+ ) {
74
87
  this._outputSchema = outputSchema;
75
88
  this._producerMode = producerMode;
76
89
  this._serverId = serverId;
77
90
  this._requestId = requestId;
91
+ this.auth = authContext ?? AuthContext.anonymous();
78
92
  }
79
93
 
80
94
  get outputSchema(): Schema {
@@ -133,25 +133,39 @@ export function buildLogBatch(
133
133
  return buildEmptyBatch(schema, metadata);
134
134
  }
135
135
 
136
+ /**
137
+ * Recursively create empty (0-row) Data for any Arrow type,
138
+ * including complex types (Struct, List, FixedSizeList, Map).
139
+ */
140
+ function makeEmptyData(type: DataType): Data {
141
+ if (DataType.isStruct(type)) {
142
+ const children = type.children.map((f: Field) => makeEmptyData(f.type));
143
+ return makeData({ type, length: 0, children, nullCount: 0 });
144
+ }
145
+ if (DataType.isList(type)) {
146
+ const childData = makeEmptyData(type.children[0].type);
147
+ return makeData({ type, length: 0, children: [childData], nullCount: 0, valueOffsets: new Int32Array([0]) } as any);
148
+ }
149
+ if (DataType.isFixedSizeList(type)) {
150
+ const childData = makeEmptyData(type.children[0].type);
151
+ return makeData({ type, length: 0, child: childData, nullCount: 0 } as any);
152
+ }
153
+ if (DataType.isMap(type)) {
154
+ const entryType = type.children[0]?.type;
155
+ const entryData = entryType
156
+ ? makeEmptyData(entryType)
157
+ : makeData({ type: new Struct([]), length: 0, children: [], nullCount: 0 });
158
+ return makeData({ type, length: 0, children: [entryData], nullCount: 0, valueOffsets: new Int32Array([0]) } as any);
159
+ }
160
+ return makeData({ type, length: 0, nullCount: 0 });
161
+ }
162
+
136
163
  /**
137
164
  * Build a 0-row batch from a schema with metadata.
138
165
  * Used for error/log batches.
139
166
  */
140
167
  export function buildEmptyBatch(schema: Schema, metadata?: Map<string, string>): RecordBatch {
141
- const children = schema.fields.map((f: Field) => {
142
- return makeData({ type: f.type, length: 0, nullCount: 0 });
143
- });
144
-
145
- if (schema.fields.length === 0) {
146
- const structType = new Struct(schema.fields);
147
- const data = makeData({
148
- type: structType,
149
- length: 0,
150
- children: [],
151
- nullCount: 0,
152
- });
153
- return new RecordBatch(schema, data, metadata);
154
- }
168
+ const children = schema.fields.map((f: Field) => makeEmptyData(f.type));
155
169
 
156
170
  const structType = new Struct(schema.fields);
157
171
  const data = makeData({