feat: Complete zCode CLI X with Telegram bot integration

- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
This commit is contained in:
admin
2026-05-05 09:01:26 +00:00
Unverified
parent 4a7035dd92
commit 875c7f9b91
24688 changed files with 3224957 additions and 221 deletions

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { ServiceDefinition } from './make-client';
import { Server, UntypedServiceImplementation } from './server';
interface GetServiceDefinition {
(): ServiceDefinition;
}
interface GetHandlers {
(): UntypedServiceImplementation;
}
const registeredAdminServices: {
getServiceDefinition: GetServiceDefinition;
getHandlers: GetHandlers;
}[] = [];
export function registerAdminService(
getServiceDefinition: GetServiceDefinition,
getHandlers: GetHandlers
) {
registeredAdminServices.push({ getServiceDefinition, getHandlers });
}
export function addAdminServicesToServer(server: Server): void {
for (const { getServiceDefinition, getHandlers } of registeredAdminServices) {
server.addService(getServiceDefinition(), getHandlers());
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { PeerCertificate } from "tls";
export interface AuthContext {
transportSecurityType?: string;
sslPeerCertificate?: PeerCertificate;
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { LogVerbosity } from './constants';
import * as logging from './logging';
const TRACER_NAME = 'backoff';
const INITIAL_BACKOFF_MS = 1000;
const BACKOFF_MULTIPLIER = 1.6;
const MAX_BACKOFF_MS = 120000;
const BACKOFF_JITTER = 0.2;
/**
* Get a number uniformly at random in the range [min, max)
* @param min
* @param max
*/
function uniformRandom(min: number, max: number) {
return Math.random() * (max - min) + min;
}
export interface BackoffOptions {
initialDelay?: number;
multiplier?: number;
jitter?: number;
maxDelay?: number;
}
export class BackoffTimeout {
/**
* The delay time at the start, and after each reset.
*/
private readonly initialDelay: number = INITIAL_BACKOFF_MS;
/**
* The exponential backoff multiplier.
*/
private readonly multiplier: number = BACKOFF_MULTIPLIER;
/**
* The maximum delay time
*/
private readonly maxDelay: number = MAX_BACKOFF_MS;
/**
* The maximum fraction by which the delay time can randomly vary after
* applying the multiplier.
*/
private readonly jitter: number = BACKOFF_JITTER;
/**
* The delay time for the next time the timer runs.
*/
private nextDelay: number;
/**
* The handle of the underlying timer. If running is false, this value refers
* to an object representing a timer that has ended, but it can still be
* interacted with without error.
*/
private timerId: NodeJS.Timeout;
/**
* Indicates whether the timer is currently running.
*/
private running = false;
/**
* Indicates whether the timer should keep the Node process running if no
* other async operation is doing so.
*/
private hasRef = true;
/**
* The time that the currently running timer was started. Only valid if
* running is true.
*/
private startTime: Date = new Date();
/**
* The approximate time that the currently running timer will end. Only valid
* if running is true.
*/
private endTime: Date = new Date();
private id: number;
private static nextId = 0;
constructor(private callback: () => void, options?: BackoffOptions) {
this.id = BackoffTimeout.getNextId();
if (options) {
if (options.initialDelay) {
this.initialDelay = options.initialDelay;
}
if (options.multiplier) {
this.multiplier = options.multiplier;
}
if (options.jitter) {
this.jitter = options.jitter;
}
if (options.maxDelay) {
this.maxDelay = options.maxDelay;
}
}
this.trace('constructed initialDelay=' + this.initialDelay + ' multiplier=' + this.multiplier + ' jitter=' + this.jitter + ' maxDelay=' + this.maxDelay);
this.nextDelay = this.initialDelay;
this.timerId = setTimeout(() => {}, 0);
clearTimeout(this.timerId);
}
private static getNextId() {
return this.nextId++;
}
private trace(text: string) {
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '{' + this.id + '} ' + text);
}
private runTimer(delay: number) {
this.trace('runTimer(delay=' + delay + ')');
this.endTime = this.startTime;
this.endTime.setMilliseconds(
this.endTime.getMilliseconds() + delay
);
clearTimeout(this.timerId);
this.timerId = setTimeout(() => {
this.trace('timer fired');
this.running = false;
this.callback();
}, delay);
if (!this.hasRef) {
this.timerId.unref?.();
}
}
/**
* Call the callback after the current amount of delay time
*/
runOnce() {
this.trace('runOnce()');
this.running = true;
this.startTime = new Date();
this.runTimer(this.nextDelay);
const nextBackoff = Math.min(
this.nextDelay * this.multiplier,
this.maxDelay
);
const jitterMagnitude = nextBackoff * this.jitter;
this.nextDelay =
nextBackoff + uniformRandom(-jitterMagnitude, jitterMagnitude);
}
/**
* Stop the timer. The callback will not be called until `runOnce` is called
* again.
*/
stop() {
this.trace('stop()');
clearTimeout(this.timerId);
this.running = false;
}
/**
* Reset the delay time to its initial value. If the timer is still running,
* retroactively apply that reset to the current timer.
*/
reset() {
this.trace('reset() running=' + this.running);
this.nextDelay = this.initialDelay;
if (this.running) {
const now = new Date();
const newEndTime = this.startTime;
newEndTime.setMilliseconds(newEndTime.getMilliseconds() + this.nextDelay);
clearTimeout(this.timerId);
if (now < newEndTime) {
this.runTimer(newEndTime.getTime() - now.getTime());
} else {
this.running = false;
}
}
}
/**
* Check whether the timer is currently running.
*/
isRunning() {
return this.running;
}
/**
* Set that while the timer is running, it should keep the Node process
* running.
*/
ref() {
this.hasRef = true;
this.timerId.ref?.();
}
/**
* Set that while the timer is running, it should not keep the Node process
* running.
*/
unref() {
this.hasRef = false;
this.timerId.unref?.();
}
/**
* Get the approximate timestamp of when the timer will fire. Only valid if
* this.isRunning() is true.
*/
getEndTime() {
return this.endTime;
}
}

View File

@@ -0,0 +1,227 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { Metadata } from './metadata';
export interface CallMetadataOptions {
method_name: string;
service_url: string;
}
export type CallMetadataGenerator = (
options: CallMetadataOptions,
cb: (err: Error | null, metadata?: Metadata) => void
) => void;
// google-auth-library pre-v2.0.0 does not have getRequestHeaders
// but has getRequestMetadata, which is deprecated in v2.0.0
export interface OldOAuth2Client {
getRequestMetadata: (
url: string,
callback: (
err: Error | null,
headers?: {
[index: string]: string;
}
) => void
) => void;
}
export interface CurrentOAuth2Client {
getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>;
}
export type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client;
function isCurrentOauth2Client(
client: OAuth2Client
): client is CurrentOAuth2Client {
return (
'getRequestHeaders' in client &&
typeof client.getRequestHeaders === 'function'
);
}
/**
* A class that represents a generic method of adding authentication-related
* metadata on a per-request basis.
*/
export abstract class CallCredentials {
/**
* Asynchronously generates a new Metadata object.
* @param options Options used in generating the Metadata object.
*/
abstract generateMetadata(options: CallMetadataOptions): Promise<Metadata>;
/**
* Creates a new CallCredentials object from properties of both this and
* another CallCredentials object. This object's metadata generator will be
* called first.
* @param callCredentials The other CallCredentials object.
*/
abstract compose(callCredentials: CallCredentials): CallCredentials;
/**
* Check whether two call credentials objects are equal. Separate
* SingleCallCredentials with identical metadata generator functions are
* equal.
* @param other The other CallCredentials object to compare with.
*/
abstract _equals(other: CallCredentials): boolean;
/**
* Creates a new CallCredentials object from a given function that generates
* Metadata objects.
* @param metadataGenerator A function that accepts a set of options, and
* generates a Metadata object based on these options, which is passed back
* to the caller via a supplied (err, metadata) callback.
*/
static createFromMetadataGenerator(
metadataGenerator: CallMetadataGenerator
): CallCredentials {
return new SingleCallCredentials(metadataGenerator);
}
/**
* Create a gRPC credential from a Google credential object.
* @param googleCredentials The authentication client to use.
* @return The resulting CallCredentials object.
*/
static createFromGoogleCredential(
googleCredentials: OAuth2Client
): CallCredentials {
return CallCredentials.createFromMetadataGenerator((options, callback) => {
let getHeaders: Promise<{ [index: string]: string }>;
if (isCurrentOauth2Client(googleCredentials)) {
getHeaders = googleCredentials.getRequestHeaders(options.service_url);
} else {
getHeaders = new Promise((resolve, reject) => {
googleCredentials.getRequestMetadata(
options.service_url,
(err, headers) => {
if (err) {
reject(err);
return;
}
if (!headers) {
reject(new Error('Headers not set by metadata plugin'));
return;
}
resolve(headers);
}
);
});
}
getHeaders.then(
headers => {
const metadata = new Metadata();
for (const key of Object.keys(headers)) {
metadata.add(key, headers[key]);
}
callback(null, metadata);
},
err => {
callback(err);
}
);
});
}
static createEmpty(): CallCredentials {
return new EmptyCallCredentials();
}
}
class ComposedCallCredentials extends CallCredentials {
constructor(private creds: CallCredentials[]) {
super();
}
async generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
const base: Metadata = new Metadata();
const generated: Metadata[] = await Promise.all(
this.creds.map(cred => cred.generateMetadata(options))
);
for (const gen of generated) {
base.merge(gen);
}
return base;
}
compose(other: CallCredentials): CallCredentials {
return new ComposedCallCredentials(this.creds.concat([other]));
}
_equals(other: CallCredentials): boolean {
if (this === other) {
return true;
}
if (other instanceof ComposedCallCredentials) {
return this.creds.every((value, index) =>
value._equals(other.creds[index])
);
} else {
return false;
}
}
}
class SingleCallCredentials extends CallCredentials {
constructor(private metadataGenerator: CallMetadataGenerator) {
super();
}
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
return new Promise<Metadata>((resolve, reject) => {
this.metadataGenerator(options, (err, metadata) => {
if (metadata !== undefined) {
resolve(metadata);
} else {
reject(err);
}
});
});
}
compose(other: CallCredentials): CallCredentials {
return new ComposedCallCredentials([this, other]);
}
_equals(other: CallCredentials): boolean {
if (this === other) {
return true;
}
if (other instanceof SingleCallCredentials) {
return this.metadataGenerator === other.metadataGenerator;
} else {
return false;
}
}
}
class EmptyCallCredentials extends CallCredentials {
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
return Promise.resolve(new Metadata());
}
compose(other: CallCredentials): CallCredentials {
return other;
}
_equals(other: CallCredentials): boolean {
return other instanceof EmptyCallCredentials;
}
}

View File

@@ -0,0 +1,208 @@
/*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { AuthContext } from './auth-context';
import { CallCredentials } from './call-credentials';
import { Status } from './constants';
import { Deadline } from './deadline';
import { Metadata } from './metadata';
import { ServerSurfaceCall } from './server-call';
export interface CallStreamOptions {
deadline: Deadline;
flags: number;
host: string;
parentCall: ServerSurfaceCall | null;
}
export type PartialCallStreamOptions = Partial<CallStreamOptions>;
export interface StatusObject {
code: Status;
details: string;
metadata: Metadata;
}
export type PartialStatusObject = Pick<StatusObject, 'code' | 'details'> & {
metadata?: Metadata | null | undefined;
};
export interface StatusOrOk<T> {
ok: true;
value: T;
}
export interface StatusOrError {
ok: false;
error: StatusObject;
}
export type StatusOr<T> = StatusOrOk<T> | StatusOrError;
export function statusOrFromValue<T>(value: T): StatusOr<T> {
return {
ok: true,
value: value
};
}
export function statusOrFromError<T>(error: PartialStatusObject): StatusOr<T> {
return {
ok: false,
error: {
...error,
metadata: error.metadata ?? new Metadata()
}
};
}
export const enum WriteFlags {
BufferHint = 1,
NoCompress = 2,
WriteThrough = 4,
}
export interface WriteObject {
message: Buffer;
flags?: number;
}
export interface MetadataListener {
(metadata: Metadata, next: (metadata: Metadata) => void): void;
}
export interface MessageListener {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(message: any, next: (message: any) => void): void;
}
export interface StatusListener {
(status: StatusObject, next: (status: StatusObject) => void): void;
}
export interface FullListener {
onReceiveMetadata: MetadataListener;
onReceiveMessage: MessageListener;
onReceiveStatus: StatusListener;
}
export type Listener = Partial<FullListener>;
/**
* An object with methods for handling the responses to a call.
*/
export interface InterceptingListener {
onReceiveMetadata(metadata: Metadata): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message: any): void;
onReceiveStatus(status: StatusObject): void;
}
export function isInterceptingListener(
listener: Listener | InterceptingListener
): listener is InterceptingListener {
return (
listener.onReceiveMetadata !== undefined &&
listener.onReceiveMetadata.length === 1
);
}
export class InterceptingListenerImpl implements InterceptingListener {
private processingMetadata = false;
private hasPendingMessage = false;
private pendingMessage: any;
private processingMessage = false;
private pendingStatus: StatusObject | null = null;
constructor(
private listener: FullListener,
private nextListener: InterceptingListener
) {}
private processPendingMessage() {
if (this.hasPendingMessage) {
this.nextListener.onReceiveMessage(this.pendingMessage);
this.pendingMessage = null;
this.hasPendingMessage = false;
}
}
private processPendingStatus() {
if (this.pendingStatus) {
this.nextListener.onReceiveStatus(this.pendingStatus);
}
}
onReceiveMetadata(metadata: Metadata): void {
this.processingMetadata = true;
this.listener.onReceiveMetadata(metadata, metadata => {
this.processingMetadata = false;
this.nextListener.onReceiveMetadata(metadata);
this.processPendingMessage();
this.processPendingStatus();
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message: any): void {
/* If this listener processes messages asynchronously, the last message may
* be reordered with respect to the status */
this.processingMessage = true;
this.listener.onReceiveMessage(message, msg => {
this.processingMessage = false;
if (this.processingMetadata) {
this.pendingMessage = msg;
this.hasPendingMessage = true;
} else {
this.nextListener.onReceiveMessage(msg);
this.processPendingStatus();
}
});
}
onReceiveStatus(status: StatusObject): void {
this.listener.onReceiveStatus(status, processedStatus => {
if (this.processingMetadata || this.processingMessage) {
this.pendingStatus = processedStatus;
} else {
this.nextListener.onReceiveStatus(processedStatus);
}
});
}
}
export interface WriteCallback {
(error?: Error | null): void;
}
export interface MessageContext {
callback?: WriteCallback;
flags?: number;
}
export interface Call {
cancelWithStatus(status: Status, details: string): void;
getPeer(): string;
start(metadata: Metadata, listener: InterceptingListener): void;
sendMessageWithContext(context: MessageContext, message: Buffer): void;
startRead(): void;
halfClose(): void;
getCallNumber(): number;
setCredentials(credentials: CallCredentials): void;
getAuthContext(): AuthContext | null;
}
export interface DeadlineInfoProvider {
getDeadlineInfo(): string[];
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
let nextCallNumber = 0;
export function getNextCallNumber() {
return nextCallNumber++;
}

View File

@@ -0,0 +1,218 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { EventEmitter } from 'events';
import { Duplex, Readable, Writable } from 'stream';
import { StatusObject, MessageContext } from './call-interface';
import { Status } from './constants';
import { EmitterAugmentation1 } from './events';
import { Metadata } from './metadata';
import { ObjectReadable, ObjectWritable, WriteCallback } from './object-stream';
import { InterceptingCallInterface } from './client-interceptors';
import { AuthContext } from './auth-context';
/**
* A type extending the built-in Error object with additional fields.
*/
export type ServiceError = StatusObject & Error;
/**
* A base type for all user-facing values returned by client-side method calls.
*/
export type SurfaceCall = {
call?: InterceptingCallInterface;
cancel(): void;
getPeer(): string;
getAuthContext(): AuthContext | null;
} & EmitterAugmentation1<'metadata', Metadata> &
EmitterAugmentation1<'status', StatusObject> &
EventEmitter;
/**
* A type representing the return value of a unary method call.
*/
export type ClientUnaryCall = SurfaceCall;
/**
* A type representing the return value of a server stream method call.
*/
export type ClientReadableStream<ResponseType> = {
deserialize: (chunk: Buffer) => ResponseType;
} & SurfaceCall &
ObjectReadable<ResponseType>;
/**
* A type representing the return value of a client stream method call.
*/
export type ClientWritableStream<RequestType> = {
serialize: (value: RequestType) => Buffer;
} & SurfaceCall &
ObjectWritable<RequestType>;
/**
* A type representing the return value of a bidirectional stream method call.
*/
export type ClientDuplexStream<RequestType, ResponseType> =
ClientWritableStream<RequestType> & ClientReadableStream<ResponseType>;
/**
* Construct a ServiceError from a StatusObject. This function exists primarily
* as an attempt to make the error stack trace clearly communicate that the
* error is not necessarily a problem in gRPC itself.
* @param status
*/
export function callErrorFromStatus(
status: StatusObject,
callerStack: string
): ServiceError {
const message = `${status.code} ${Status[status.code]}: ${status.details}`;
const error = new Error(message);
const stack = `${error.stack}\nfor call at\n${callerStack}`;
return Object.assign(new Error(message), status, { stack });
}
export class ClientUnaryCallImpl
extends EventEmitter
implements ClientUnaryCall
{
public call?: InterceptingCallInterface;
constructor() {
super();
}
cancel(): void {
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
}
getPeer(): string {
return this.call?.getPeer() ?? 'unknown';
}
getAuthContext(): AuthContext | null {
return this.call?.getAuthContext() ?? null;
}
}
export class ClientReadableStreamImpl<ResponseType>
extends Readable
implements ClientReadableStream<ResponseType>
{
public call?: InterceptingCallInterface;
constructor(readonly deserialize: (chunk: Buffer) => ResponseType) {
super({ objectMode: true });
}
cancel(): void {
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
}
getPeer(): string {
return this.call?.getPeer() ?? 'unknown';
}
getAuthContext(): AuthContext | null {
return this.call?.getAuthContext() ?? null;
}
_read(_size: number): void {
this.call?.startRead();
}
}
export class ClientWritableStreamImpl<RequestType>
extends Writable
implements ClientWritableStream<RequestType>
{
public call?: InterceptingCallInterface;
constructor(readonly serialize: (value: RequestType) => Buffer) {
super({ objectMode: true });
}
cancel(): void {
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
}
getPeer(): string {
return this.call?.getPeer() ?? 'unknown';
}
getAuthContext(): AuthContext | null {
return this.call?.getAuthContext() ?? null;
}
_write(chunk: RequestType, encoding: string, cb: WriteCallback) {
const context: MessageContext = {
callback: cb,
};
const flags = Number(encoding);
if (!Number.isNaN(flags)) {
context.flags = flags;
}
this.call?.sendMessageWithContext(context, chunk);
}
_final(cb: Function) {
this.call?.halfClose();
cb();
}
}
export class ClientDuplexStreamImpl<RequestType, ResponseType>
extends Duplex
implements ClientDuplexStream<RequestType, ResponseType>
{
public call?: InterceptingCallInterface;
constructor(
readonly serialize: (value: RequestType) => Buffer,
readonly deserialize: (chunk: Buffer) => ResponseType
) {
super({ objectMode: true });
}
cancel(): void {
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
}
getPeer(): string {
return this.call?.getPeer() ?? 'unknown';
}
getAuthContext(): AuthContext | null {
return this.call?.getAuthContext() ?? null;
}
_read(_size: number): void {
this.call?.startRead();
}
_write(chunk: RequestType, encoding: string, cb: WriteCallback) {
const context: MessageContext = {
callback: cb,
};
const flags = Number(encoding);
if (!Number.isNaN(flags)) {
context.flags = flags;
}
this.call?.sendMessageWithContext(context, chunk);
}
_final(cb: Function) {
this.call?.halfClose();
cb();
}
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import * as fs from 'fs';
import * as logging from './logging';
import { LogVerbosity } from './constants';
import { promisify } from 'util';
const TRACER_NAME = 'certificate_provider';
function trace(text: string) {
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
}
export interface CaCertificateUpdate {
caCertificate: Buffer;
}
export interface IdentityCertificateUpdate {
certificate: Buffer;
privateKey: Buffer;
}
export interface CaCertificateUpdateListener {
(update: CaCertificateUpdate | null): void;
}
export interface IdentityCertificateUpdateListener {
(update: IdentityCertificateUpdate | null) : void;
}
export interface CertificateProvider {
addCaCertificateListener(listener: CaCertificateUpdateListener): void;
removeCaCertificateListener(listener: CaCertificateUpdateListener): void;
addIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
removeIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
}
export interface FileWatcherCertificateProviderConfig {
certificateFile?: string | undefined;
privateKeyFile?: string | undefined;
caCertificateFile?: string | undefined;
refreshIntervalMs: number;
}
const readFilePromise = promisify(fs.readFile);
export class FileWatcherCertificateProvider implements CertificateProvider {
private refreshTimer: NodeJS.Timeout | null = null;
private fileResultPromise: Promise<[PromiseSettledResult<Buffer>, PromiseSettledResult<Buffer>, PromiseSettledResult<Buffer>]> | null = null;
private latestCaUpdate: CaCertificateUpdate | null | undefined = undefined;
private caListeners: Set<CaCertificateUpdateListener> = new Set();
private latestIdentityUpdate: IdentityCertificateUpdate | null | undefined = undefined;
private identityListeners: Set<IdentityCertificateUpdateListener> = new Set();
private lastUpdateTime: Date | null = null;
constructor(
private config: FileWatcherCertificateProviderConfig
) {
if ((config.certificateFile === undefined) !== (config.privateKeyFile === undefined)) {
throw new Error('certificateFile and privateKeyFile must be set or unset together');
}
if (config.certificateFile === undefined && config.caCertificateFile === undefined) {
throw new Error('At least one of certificateFile and caCertificateFile must be set');
}
trace('File watcher constructed with config ' + JSON.stringify(config));
}
private updateCertificates() {
if (this.fileResultPromise) {
return;
}
this.fileResultPromise = Promise.allSettled([
this.config.certificateFile ? readFilePromise(this.config.certificateFile) : Promise.reject<Buffer>(),
this.config.privateKeyFile ? readFilePromise(this.config.privateKeyFile) : Promise.reject<Buffer>(),
this.config.caCertificateFile ? readFilePromise(this.config.caCertificateFile) : Promise.reject<Buffer>()
]);
this.fileResultPromise.then(([certificateResult, privateKeyResult, caCertificateResult]) => {
if (!this.refreshTimer) {
return;
}
trace('File watcher read certificates certificate ' + certificateResult.status + ', privateKey ' + privateKeyResult.status + ', CA certificate ' + caCertificateResult.status);
this.lastUpdateTime = new Date();
this.fileResultPromise = null;
if (certificateResult.status === 'fulfilled' && privateKeyResult.status === 'fulfilled') {
this.latestIdentityUpdate = {
certificate: certificateResult.value,
privateKey: privateKeyResult.value
};
} else {
this.latestIdentityUpdate = null;
}
if (caCertificateResult.status === 'fulfilled') {
this.latestCaUpdate = {
caCertificate: caCertificateResult.value
};
} else {
this.latestCaUpdate = null;
}
for (const listener of this.identityListeners) {
listener(this.latestIdentityUpdate);
}
for (const listener of this.caListeners) {
listener(this.latestCaUpdate);
}
});
trace('File watcher initiated certificate update');
}
private maybeStartWatchingFiles() {
if (!this.refreshTimer) {
/* Perform the first read immediately, but only if there was not already
* a recent read, to avoid reading from the filesystem significantly more
* frequently than configured if the provider quickly switches between
* used and unused. */
const timeSinceLastUpdate = this.lastUpdateTime ? (new Date()).getTime() - this.lastUpdateTime.getTime() : Infinity;
if (timeSinceLastUpdate > this.config.refreshIntervalMs) {
this.updateCertificates();
}
if (timeSinceLastUpdate > this.config.refreshIntervalMs * 2) {
// Clear out old updates if they are definitely stale
this.latestCaUpdate = undefined;
this.latestIdentityUpdate = undefined;
}
this.refreshTimer = setInterval(() => this.updateCertificates(), this.config.refreshIntervalMs);
trace('File watcher started watching');
}
}
private maybeStopWatchingFiles() {
if (this.caListeners.size === 0 && this.identityListeners.size === 0) {
this.fileResultPromise = null;
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
}
}
addCaCertificateListener(listener: CaCertificateUpdateListener): void {
this.caListeners.add(listener);
this.maybeStartWatchingFiles();
if (this.latestCaUpdate !== undefined) {
process.nextTick(listener, this.latestCaUpdate);
}
}
removeCaCertificateListener(listener: CaCertificateUpdateListener): void {
this.caListeners.delete(listener);
this.maybeStopWatchingFiles();
}
addIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void {
this.identityListeners.add(listener);
this.maybeStartWatchingFiles();
if (this.latestIdentityUpdate !== undefined) {
process.nextTick(listener, this.latestIdentityUpdate);
}
}
removeIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void {
this.identityListeners.delete(listener);
this.maybeStopWatchingFiles();
}
}

View File

@@ -0,0 +1,523 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import {
ConnectionOptions,
createSecureContext,
PeerCertificate,
SecureContext,
checkServerIdentity,
connect as tlsConnect
} from 'tls';
import { CallCredentials } from './call-credentials';
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
import { CaCertificateUpdate, CaCertificateUpdateListener, CertificateProvider, IdentityCertificateUpdate, IdentityCertificateUpdateListener } from './certificate-provider';
import { Socket } from 'net';
import { ChannelOptions } from './channel-options';
import { GrpcUri, parseUri, splitHostPort } from './uri-parser';
import { getDefaultAuthority } from './resolver';
import { log } from './logging';
import { LogVerbosity } from './constants';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function verifyIsBufferOrNull(obj: any, friendlyName: string): void {
if (obj && !(obj instanceof Buffer)) {
throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`);
}
}
/**
* A callback that will receive the expected hostname and presented peer
* certificate as parameters. The callback should return an error to
* indicate that the presented certificate is considered invalid and
* otherwise returned undefined.
*/
export type CheckServerIdentityCallback = (
hostname: string,
cert: PeerCertificate
) => Error | undefined;
/**
* Additional peer verification options that can be set when creating
* SSL credentials.
*/
export interface VerifyOptions {
/**
* If set, this callback will be invoked after the usual hostname verification
* has been performed on the peer certificate.
*/
checkServerIdentity?: CheckServerIdentityCallback;
rejectUnauthorized?: boolean;
}
export interface SecureConnectResult {
socket: Socket;
secure: boolean;
}
export interface SecureConnector {
connect(socket: Socket): Promise<SecureConnectResult>;
waitForReady(): Promise<void>;
getCallCredentials(): CallCredentials;
destroy(): void;
}
/**
* A class that contains credentials for communicating over a channel, as well
* as a set of per-call credentials, which are applied to every method call made
* over a channel initialized with an instance of this class.
*/
export abstract class ChannelCredentials {
/**
* Returns a copy of this object with the included set of per-call credentials
* expanded to include callCredentials.
* @param callCredentials A CallCredentials object to associate with this
* instance.
*/
compose(callCredentials: CallCredentials): ChannelCredentials {
return new ComposedChannelCredentialsImpl(this, callCredentials);
}
/**
* Indicates whether this credentials object creates a secure channel.
*/
abstract _isSecure(): boolean;
/**
* Check whether two channel credentials objects are equal. Two secure
* credentials are equal if they were constructed with the same parameters.
* @param other The other ChannelCredentials Object
*/
abstract _equals(other: ChannelCredentials): boolean;
abstract _createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector;
/**
* Return a new ChannelCredentials instance with a given set of credentials.
* The resulting instance can be used to construct a Channel that communicates
* over TLS.
* @param rootCerts The root certificate data.
* @param privateKey The client certificate private key, if available.
* @param certChain The client certificate key chain, if available.
* @param verifyOptions Additional options to modify certificate verification
*/
static createSsl(
rootCerts?: Buffer | null,
privateKey?: Buffer | null,
certChain?: Buffer | null,
verifyOptions?: VerifyOptions
): ChannelCredentials {
verifyIsBufferOrNull(rootCerts, 'Root certificate');
verifyIsBufferOrNull(privateKey, 'Private key');
verifyIsBufferOrNull(certChain, 'Certificate chain');
if (privateKey && !certChain) {
throw new Error(
'Private key must be given with accompanying certificate chain'
);
}
if (!privateKey && certChain) {
throw new Error(
'Certificate chain must be given with accompanying private key'
);
}
const secureContext = createSecureContext({
ca: rootCerts ?? getDefaultRootsData() ?? undefined,
key: privateKey ?? undefined,
cert: certChain ?? undefined,
ciphers: CIPHER_SUITES,
});
return new SecureChannelCredentialsImpl(secureContext, verifyOptions ?? {});
}
/**
* Return a new ChannelCredentials instance with credentials created using
* the provided secureContext. The resulting instances can be used to
* construct a Channel that communicates over TLS. gRPC will not override
* anything in the provided secureContext, so the environment variables
* GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
* not be applied.
* @param secureContext The return value of tls.createSecureContext()
* @param verifyOptions Additional options to modify certificate verification
*/
static createFromSecureContext(
secureContext: SecureContext,
verifyOptions?: VerifyOptions
): ChannelCredentials {
return new SecureChannelCredentialsImpl(secureContext, verifyOptions ?? {});
}
/**
* Return a new ChannelCredentials instance with no credentials.
*/
static createInsecure(): ChannelCredentials {
return new InsecureChannelCredentialsImpl();
}
}
class InsecureChannelCredentialsImpl extends ChannelCredentials {
constructor() {
super();
}
override compose(callCredentials: CallCredentials): never {
throw new Error('Cannot compose insecure credentials');
}
_isSecure(): boolean {
return false;
}
_equals(other: ChannelCredentials): boolean {
return other instanceof InsecureChannelCredentialsImpl;
}
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
return {
connect(socket) {
return Promise.resolve({
socket,
secure: false
});
},
waitForReady: () => {
return Promise.resolve();
},
getCallCredentials: () => {
return callCredentials ?? CallCredentials.createEmpty();
},
destroy() {}
}
}
}
function getConnectionOptions(secureContext: SecureContext, verifyOptions: VerifyOptions, channelTarget: GrpcUri, options: ChannelOptions): ConnectionOptions {
const connectionOptions: ConnectionOptions = {
secureContext: secureContext
};
let realTarget: GrpcUri = channelTarget;
if ('grpc.http_connect_target' in options) {
const parsedTarget = parseUri(options['grpc.http_connect_target']!);
if (parsedTarget) {
realTarget = parsedTarget;
}
}
const targetPath = getDefaultAuthority(realTarget);
const hostPort = splitHostPort(targetPath);
const remoteHost = hostPort?.host ?? targetPath;
connectionOptions.host = remoteHost;
if (verifyOptions.checkServerIdentity) {
connectionOptions.checkServerIdentity = verifyOptions.checkServerIdentity;
}
if (verifyOptions.rejectUnauthorized !== undefined) {
connectionOptions.rejectUnauthorized = verifyOptions.rejectUnauthorized;
}
connectionOptions.ALPNProtocols = ['h2'];
if (options['grpc.ssl_target_name_override']) {
const sslTargetNameOverride = options['grpc.ssl_target_name_override']!;
const originalCheckServerIdentity =
connectionOptions.checkServerIdentity ?? checkServerIdentity;
connectionOptions.checkServerIdentity = (
host: string,
cert: PeerCertificate
): Error | undefined => {
return originalCheckServerIdentity(sslTargetNameOverride, cert);
};
connectionOptions.servername = sslTargetNameOverride;
} else {
connectionOptions.servername = remoteHost;
}
if (options['grpc-node.tls_enable_trace']) {
connectionOptions.enableTrace = true;
}
return connectionOptions;
}
class SecureConnectorImpl implements SecureConnector {
constructor(private connectionOptions: ConnectionOptions, private callCredentials: CallCredentials) {
}
connect(socket: Socket): Promise<SecureConnectResult> {
const tlsConnectOptions: ConnectionOptions = {
socket: socket,
...this.connectionOptions
};
return new Promise<SecureConnectResult>((resolve, reject) => {
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
if ((this.connectionOptions.rejectUnauthorized ?? true) && !tlsSocket.authorized) {
reject(tlsSocket.authorizationError);
return;
}
resolve({
socket: tlsSocket,
secure: true
})
});
tlsSocket.on('error', (error: Error) => {
reject(error);
});
});
}
waitForReady(): Promise<void> {
return Promise.resolve();
}
getCallCredentials(): CallCredentials {
return this.callCredentials;
}
destroy() {}
}
class SecureChannelCredentialsImpl extends ChannelCredentials {
constructor(
private secureContext: SecureContext,
private verifyOptions: VerifyOptions
) {
super();
}
_isSecure(): boolean {
return true;
}
_equals(other: ChannelCredentials): boolean {
if (this === other) {
return true;
}
if (other instanceof SecureChannelCredentialsImpl) {
return (
this.secureContext === other.secureContext &&
this.verifyOptions.checkServerIdentity ===
other.verifyOptions.checkServerIdentity
);
} else {
return false;
}
}
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
const connectionOptions = getConnectionOptions(this.secureContext, this.verifyOptions, channelTarget, options);
return new SecureConnectorImpl(connectionOptions, callCredentials ?? CallCredentials.createEmpty());
}
}
class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
private refcount: number = 0;
/**
* `undefined` means that the certificates have not yet been loaded. `null`
* means that an attempt to load them has completed, and has failed.
*/
private latestCaUpdate: CaCertificateUpdate | null | undefined = undefined;
/**
* `undefined` means that the certificates have not yet been loaded. `null`
* means that an attempt to load them has completed, and has failed.
*/
private latestIdentityUpdate: IdentityCertificateUpdate | null | undefined = undefined;
private caCertificateUpdateListener: CaCertificateUpdateListener = this.handleCaCertificateUpdate.bind(this);
private identityCertificateUpdateListener: IdentityCertificateUpdateListener = this.handleIdentityCertitificateUpdate.bind(this);
private secureContextWatchers: ((context: SecureContext | null) => void)[] = [];
private static SecureConnectorImpl = class implements SecureConnector {
constructor(private parent: CertificateProviderChannelCredentialsImpl, private channelTarget: GrpcUri, private options: ChannelOptions, private callCredentials: CallCredentials) {}
connect(socket: Socket): Promise<SecureConnectResult> {
return new Promise((resolve, reject) => {
const secureContext = this.parent.getLatestSecureContext();
if (!secureContext) {
reject(new Error('Failed to load credentials'));
return;
}
if (socket.closed) {
reject(new Error('Socket closed while loading credentials'));
}
const connnectionOptions = getConnectionOptions(secureContext, this.parent.verifyOptions, this.channelTarget, this.options);
const tlsConnectOptions: ConnectionOptions = {
socket: socket,
...connnectionOptions
}
const closeCallback = () => {
reject(new Error('Socket closed'));
};
const errorCallback = (error: Error) => {
reject(error);
}
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
tlsSocket.removeListener('close', closeCallback);
tlsSocket.removeListener('error', errorCallback);
if ((this.parent.verifyOptions.rejectUnauthorized ?? true) && !tlsSocket.authorized) {
reject(tlsSocket.authorizationError);
return;
}
resolve({
socket: tlsSocket,
secure: true
});
});
tlsSocket.once('close', closeCallback);
tlsSocket.once('error', errorCallback);
});
}
async waitForReady(): Promise<void> {
await this.parent.getSecureContext();
}
getCallCredentials(): CallCredentials {
return this.callCredentials;
}
destroy() {
this.parent.unref();
}
}
constructor(
private caCertificateProvider: CertificateProvider,
private identityCertificateProvider: CertificateProvider | null,
private verifyOptions: VerifyOptions
) {
super();
}
_isSecure(): boolean {
return true;
}
_equals(other: ChannelCredentials): boolean {
if (this === other) {
return true;
}
if (other instanceof CertificateProviderChannelCredentialsImpl) {
return this.caCertificateProvider === other.caCertificateProvider &&
this.identityCertificateProvider === other.identityCertificateProvider &&
this.verifyOptions?.checkServerIdentity === other.verifyOptions?.checkServerIdentity;
} else {
return false;
}
}
private ref(): void {
if (this.refcount === 0) {
this.caCertificateProvider.addCaCertificateListener(this.caCertificateUpdateListener);
this.identityCertificateProvider?.addIdentityCertificateListener(this.identityCertificateUpdateListener);
}
this.refcount += 1;
}
private unref(): void {
this.refcount -= 1;
if (this.refcount === 0) {
this.caCertificateProvider.removeCaCertificateListener(this.caCertificateUpdateListener);
this.identityCertificateProvider?.removeIdentityCertificateListener(this.identityCertificateUpdateListener);
}
}
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
this.ref();
return new CertificateProviderChannelCredentialsImpl.SecureConnectorImpl(this, channelTarget, options, callCredentials ?? CallCredentials.createEmpty());
}
private maybeUpdateWatchers() {
if (this.hasReceivedUpdates()) {
for (const watcher of this.secureContextWatchers) {
watcher(this.getLatestSecureContext());
}
this.secureContextWatchers = [];
}
}
private handleCaCertificateUpdate(update: CaCertificateUpdate | null) {
this.latestCaUpdate = update;
this.maybeUpdateWatchers();
}
private handleIdentityCertitificateUpdate(update: IdentityCertificateUpdate | null) {
this.latestIdentityUpdate = update;
this.maybeUpdateWatchers();
}
private hasReceivedUpdates(): boolean {
if (this.latestCaUpdate === undefined) {
return false;
}
if (this.identityCertificateProvider && this.latestIdentityUpdate === undefined) {
return false;
}
return true;
}
private getSecureContext(): Promise<SecureContext | null> {
if (this.hasReceivedUpdates()) {
return Promise.resolve(this.getLatestSecureContext());
} else {
return new Promise(resolve => {
this.secureContextWatchers.push(resolve);
});
}
}
private getLatestSecureContext(): SecureContext | null {
if (!this.latestCaUpdate) {
return null;
}
if (this.identityCertificateProvider !== null && !this.latestIdentityUpdate) {
return null;
}
try {
return createSecureContext({
ca: this.latestCaUpdate.caCertificate,
key: this.latestIdentityUpdate?.privateKey,
cert: this.latestIdentityUpdate?.certificate,
ciphers: CIPHER_SUITES
});
} catch (e) {
log(LogVerbosity.ERROR, 'Failed to createSecureContext with error ' + (e as Error).message);
return null;
}
}
}
export function createCertificateProviderChannelCredentials(caCertificateProvider: CertificateProvider, identityCertificateProvider: CertificateProvider | null, verifyOptions?: VerifyOptions) {
return new CertificateProviderChannelCredentialsImpl(caCertificateProvider, identityCertificateProvider, verifyOptions ?? {});
}
class ComposedChannelCredentialsImpl extends ChannelCredentials {
constructor(
private channelCredentials: ChannelCredentials,
private callCredentials: CallCredentials
) {
super();
if (!channelCredentials._isSecure()) {
throw new Error('Cannot compose insecure credentials');
}
}
compose(callCredentials: CallCredentials) {
const combinedCallCredentials =
this.callCredentials.compose(callCredentials);
return new ComposedChannelCredentialsImpl(
this.channelCredentials,
combinedCallCredentials
);
}
_isSecure(): boolean {
return true;
}
_equals(other: ChannelCredentials): boolean {
if (this === other) {
return true;
}
if (other instanceof ComposedChannelCredentialsImpl) {
return (
this.channelCredentials._equals(other.channelCredentials) &&
this.callCredentials._equals(other.callCredentials)
);
} else {
return false;
}
}
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector {
const combinedCallCredentials = this.callCredentials.compose(callCredentials ?? CallCredentials.createEmpty());
return this.channelCredentials._createSecureConnector(channelTarget, options, combinedCallCredentials);
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { CompressionAlgorithms } from './compression-algorithms';
/**
* An interface that contains options used when initializing a Channel instance.
*/
export interface ChannelOptions {
'grpc.ssl_target_name_override'?: string;
'grpc.primary_user_agent'?: string;
'grpc.secondary_user_agent'?: string;
'grpc.default_authority'?: string;
'grpc.keepalive_time_ms'?: number;
'grpc.keepalive_timeout_ms'?: number;
'grpc.keepalive_permit_without_calls'?: number;
'grpc.service_config'?: string;
'grpc.max_concurrent_streams'?: number;
'grpc.initial_reconnect_backoff_ms'?: number;
'grpc.max_reconnect_backoff_ms'?: number;
'grpc.use_local_subchannel_pool'?: number;
'grpc.max_send_message_length'?: number;
'grpc.max_receive_message_length'?: number;
'grpc.enable_http_proxy'?: number;
/* http_connect_target and http_connect_creds are used for passing data
* around internally, and should not be documented as public-facing options
*/
'grpc.http_connect_target'?: string;
'grpc.http_connect_creds'?: string;
'grpc.default_compression_algorithm'?: CompressionAlgorithms;
'grpc.enable_channelz'?: number;
'grpc.dns_min_time_between_resolutions_ms'?: number;
'grpc.enable_retries'?: number;
'grpc.per_rpc_retry_buffer_size'?: number;
/* This option is pattered like a core option, but the core does not have
* this option. It is closely related to the option
* grpc.per_rpc_retry_buffer_size, which is in the core. The core will likely
* implement this functionality using the ResourceQuota mechanism, so there
* will probably not be any collision or other inconsistency. */
'grpc.retry_buffer_size'?: number;
'grpc.max_connection_age_ms'?: number;
'grpc.max_connection_age_grace_ms'?: number;
'grpc.max_connection_idle_ms'?: number;
'grpc-node.max_session_memory'?: number;
'grpc.service_config_disable_resolution'?: number;
'grpc.client_idle_timeout_ms'?: number;
/**
* Set the enableTrace option in TLS clients and servers
*/
'grpc-node.tls_enable_trace'?: number;
'grpc.lb.ring_hash.ring_size_cap'?: number;
'grpc-node.retry_max_attempts_limit'?: number;
'grpc-node.flow_control_window'?: number;
'grpc.server_call_metric_recording'?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
/**
* This is for checking provided options at runtime. This is an object for
* easier membership checking.
*/
export const recognizedOptions = {
'grpc.ssl_target_name_override': true,
'grpc.primary_user_agent': true,
'grpc.secondary_user_agent': true,
'grpc.default_authority': true,
'grpc.keepalive_time_ms': true,
'grpc.keepalive_timeout_ms': true,
'grpc.keepalive_permit_without_calls': true,
'grpc.service_config': true,
'grpc.max_concurrent_streams': true,
'grpc.initial_reconnect_backoff_ms': true,
'grpc.max_reconnect_backoff_ms': true,
'grpc.use_local_subchannel_pool': true,
'grpc.max_send_message_length': true,
'grpc.max_receive_message_length': true,
'grpc.enable_http_proxy': true,
'grpc.enable_channelz': true,
'grpc.dns_min_time_between_resolutions_ms': true,
'grpc.enable_retries': true,
'grpc.per_rpc_retry_buffer_size': true,
'grpc.retry_buffer_size': true,
'grpc.max_connection_age_ms': true,
'grpc.max_connection_age_grace_ms': true,
'grpc-node.max_session_memory': true,
'grpc.service_config_disable_resolution': true,
'grpc.client_idle_timeout_ms': true,
'grpc-node.tls_enable_trace': true,
'grpc.lb.ring_hash.ring_size_cap': true,
'grpc-node.retry_max_attempts_limit': true,
'grpc-node.flow_control_window': true,
'grpc.server_call_metric_recording': true
};
export function channelOptionsEqual(
options1: ChannelOptions,
options2: ChannelOptions
) {
const keys1 = Object.keys(options1).sort();
const keys2 = Object.keys(options2).sort();
if (keys1.length !== keys2.length) {
return false;
}
for (let i = 0; i < keys1.length; i += 1) {
if (keys1[i] !== keys2[i]) {
return false;
}
if (options1[keys1[i]] !== options2[keys2[i]]) {
return false;
}
}
return true;
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { ChannelCredentials } from './channel-credentials';
import { ChannelOptions } from './channel-options';
import { ServerSurfaceCall } from './server-call';
import { ConnectivityState } from './connectivity-state';
import type { ChannelRef } from './channelz';
import { Call } from './call-interface';
import { InternalChannel } from './internal-channel';
import { Deadline } from './deadline';
/**
* An interface that represents a communication channel to a server specified
* by a given address.
*/
export interface Channel {
/**
* Close the channel. This has the same functionality as the existing
* grpc.Client.prototype.close
*/
close(): void;
/**
* Return the target that this channel connects to
*/
getTarget(): string;
/**
* Get the channel's current connectivity state. This method is here mainly
* because it is in the existing internal Channel class, and there isn't
* another good place to put it.
* @param tryToConnect If true, the channel will start connecting if it is
* idle. Otherwise, idle channels will only start connecting when a
* call starts.
*/
getConnectivityState(tryToConnect: boolean): ConnectivityState;
/**
* Watch for connectivity state changes. This is also here mainly because
* it is in the existing external Channel class.
* @param currentState The state to watch for transitions from. This should
* always be populated by calling getConnectivityState immediately
* before.
* @param deadline A deadline for waiting for a state change
* @param callback Called with no error when a state change, or with an
* error if the deadline passes without a state change.
*/
watchConnectivityState(
currentState: ConnectivityState,
deadline: Date | number,
callback: (error?: Error) => void
): void;
/**
* Get the channelz reference object for this channel. A request to the
* channelz service for the id in this object will provide information
* about this channel.
*/
getChannelzRef(): ChannelRef;
/**
* Create a call object. Call is an opaque type that is used by the Client
* class. This function is called by the gRPC library when starting a
* request. Implementers should return an instance of Call that is returned
* from calling createCall on an instance of the provided Channel class.
* @param method The full method string to request.
* @param deadline The call deadline
* @param host A host string override for making the request
* @param parentCall A server call to propagate some information from
* @param propagateFlags A bitwise combination of elements of grpc.propagate
* that indicates what information to propagate from parentCall.
*/
createCall(
method: string,
deadline: Deadline,
host: string | null | undefined,
parentCall: ServerSurfaceCall | null,
propagateFlags: number | null | undefined
): Call;
}
export class ChannelImplementation implements Channel {
private internalChannel: InternalChannel;
constructor(
target: string,
credentials: ChannelCredentials,
options: ChannelOptions
) {
if (typeof target !== 'string') {
throw new TypeError('Channel target must be a string');
}
if (!(credentials instanceof ChannelCredentials)) {
throw new TypeError(
'Channel credentials must be a ChannelCredentials object'
);
}
if (options) {
if (typeof options !== 'object') {
throw new TypeError('Channel options must be an object');
}
}
this.internalChannel = new InternalChannel(target, credentials, options);
}
close() {
this.internalChannel.close();
}
getTarget() {
return this.internalChannel.getTarget();
}
getConnectivityState(tryToConnect: boolean) {
return this.internalChannel.getConnectivityState(tryToConnect);
}
watchConnectivityState(
currentState: ConnectivityState,
deadline: Date | number,
callback: (error?: Error) => void
): void {
this.internalChannel.watchConnectivityState(
currentState,
deadline,
callback
);
}
/**
* Get the channelz reference object for this channel. The returned value is
* garbage if channelz is disabled for this channel.
* @returns
*/
getChannelzRef() {
return this.internalChannel.getChannelzRef();
}
createCall(
method: string,
deadline: Deadline,
host: string | null | undefined,
parentCall: ServerSurfaceCall | null,
propagateFlags: number | null | undefined
): Call {
if (typeof method !== 'string') {
throw new TypeError('Channel#createCall: method must be a string');
}
if (!(typeof deadline === 'number' || deadline instanceof Date)) {
throw new TypeError(
'Channel#createCall: deadline must be a number or Date'
);
}
return this.internalChannel.createCall(
method,
deadline,
host,
parentCall,
propagateFlags
);
}
}

View File

@@ -0,0 +1,909 @@
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { isIPv4, isIPv6 } from 'net';
import { OrderedMap, type OrderedMapIterator } from '@js-sdsl/ordered-map';
import { ConnectivityState } from './connectivity-state';
import { Status } from './constants';
import { Timestamp } from './generated/google/protobuf/Timestamp';
import { Channel as ChannelMessage } from './generated/grpc/channelz/v1/Channel';
import { ChannelConnectivityState__Output } from './generated/grpc/channelz/v1/ChannelConnectivityState';
import { ChannelRef as ChannelRefMessage } from './generated/grpc/channelz/v1/ChannelRef';
import { ChannelTrace } from './generated/grpc/channelz/v1/ChannelTrace';
import { GetChannelRequest__Output } from './generated/grpc/channelz/v1/GetChannelRequest';
import { GetChannelResponse } from './generated/grpc/channelz/v1/GetChannelResponse';
import { sendUnaryData, ServerUnaryCall } from './server-call';
import { ServerRef as ServerRefMessage } from './generated/grpc/channelz/v1/ServerRef';
import { SocketRef as SocketRefMessage } from './generated/grpc/channelz/v1/SocketRef';
import {
isTcpSubchannelAddress,
SubchannelAddress,
} from './subchannel-address';
import { SubchannelRef as SubchannelRefMessage } from './generated/grpc/channelz/v1/SubchannelRef';
import { GetServerRequest__Output } from './generated/grpc/channelz/v1/GetServerRequest';
import { GetServerResponse } from './generated/grpc/channelz/v1/GetServerResponse';
import { Server as ServerMessage } from './generated/grpc/channelz/v1/Server';
import { GetServersRequest__Output } from './generated/grpc/channelz/v1/GetServersRequest';
import { GetServersResponse } from './generated/grpc/channelz/v1/GetServersResponse';
import { GetTopChannelsRequest__Output } from './generated/grpc/channelz/v1/GetTopChannelsRequest';
import { GetTopChannelsResponse } from './generated/grpc/channelz/v1/GetTopChannelsResponse';
import { GetSubchannelRequest__Output } from './generated/grpc/channelz/v1/GetSubchannelRequest';
import { GetSubchannelResponse } from './generated/grpc/channelz/v1/GetSubchannelResponse';
import { Subchannel as SubchannelMessage } from './generated/grpc/channelz/v1/Subchannel';
import { GetSocketRequest__Output } from './generated/grpc/channelz/v1/GetSocketRequest';
import { GetSocketResponse } from './generated/grpc/channelz/v1/GetSocketResponse';
import { Socket as SocketMessage } from './generated/grpc/channelz/v1/Socket';
import { Address } from './generated/grpc/channelz/v1/Address';
import { Security } from './generated/grpc/channelz/v1/Security';
import { GetServerSocketsRequest__Output } from './generated/grpc/channelz/v1/GetServerSocketsRequest';
import { GetServerSocketsResponse } from './generated/grpc/channelz/v1/GetServerSocketsResponse';
import {
ChannelzDefinition,
ChannelzHandlers,
} from './generated/grpc/channelz/v1/Channelz';
import { ProtoGrpcType as ChannelzProtoGrpcType } from './generated/channelz';
import type { loadSync } from '@grpc/proto-loader';
import { registerAdminService } from './admin';
import { loadPackageDefinition } from './make-client';
export type TraceSeverity =
| 'CT_UNKNOWN'
| 'CT_INFO'
| 'CT_WARNING'
| 'CT_ERROR';
interface Ref {
kind: EntityTypes;
id: number;
name: string;
}
export interface ChannelRef extends Ref {
kind: EntityTypes.channel;
}
export interface SubchannelRef extends Ref {
kind: EntityTypes.subchannel;
}
export interface ServerRef extends Ref {
kind: EntityTypes.server;
}
export interface SocketRef extends Ref {
kind: EntityTypes.socket;
}
function channelRefToMessage(ref: ChannelRef): ChannelRefMessage {
return {
channel_id: ref.id,
name: ref.name,
};
}
function subchannelRefToMessage(ref: SubchannelRef): SubchannelRefMessage {
return {
subchannel_id: ref.id,
name: ref.name,
};
}
function serverRefToMessage(ref: ServerRef): ServerRefMessage {
return {
server_id: ref.id,
};
}
function socketRefToMessage(ref: SocketRef): SocketRefMessage {
return {
socket_id: ref.id,
name: ref.name,
};
}
interface TraceEvent {
description: string;
severity: TraceSeverity;
timestamp: Date;
childChannel?: ChannelRef;
childSubchannel?: SubchannelRef;
}
/**
* The loose upper bound on the number of events that should be retained in a
* trace. This may be exceeded by up to a factor of 2. Arbitrarily chosen as a
* number that should be large enough to contain the recent relevant
* information, but small enough to not use excessive memory.
*/
const TARGET_RETAINED_TRACES = 32;
/**
* Default number of sockets/servers/channels/subchannels to return
*/
const DEFAULT_MAX_RESULTS = 100;
export class ChannelzTraceStub {
readonly events: TraceEvent[] = [];
readonly creationTimestamp: Date = new Date();
readonly eventsLogged = 0;
addTrace(): void {}
getTraceMessage(): ChannelTrace {
return {
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
num_events_logged: this.eventsLogged,
events: [],
};
}
}
export class ChannelzTrace {
events: TraceEvent[] = [];
creationTimestamp: Date;
eventsLogged = 0;
constructor() {
this.creationTimestamp = new Date();
}
addTrace(
severity: TraceSeverity,
description: string,
child?: ChannelRef | SubchannelRef
) {
const timestamp = new Date();
this.events.push({
description: description,
severity: severity,
timestamp: timestamp,
childChannel: child?.kind === 'channel' ? child : undefined,
childSubchannel: child?.kind === 'subchannel' ? child : undefined,
});
// Whenever the trace array gets too large, discard the first half
if (this.events.length >= TARGET_RETAINED_TRACES * 2) {
this.events = this.events.slice(TARGET_RETAINED_TRACES);
}
this.eventsLogged += 1;
}
getTraceMessage(): ChannelTrace {
return {
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
num_events_logged: this.eventsLogged,
events: this.events.map(event => {
return {
description: event.description,
severity: event.severity,
timestamp: dateToProtoTimestamp(event.timestamp),
channel_ref: event.childChannel
? channelRefToMessage(event.childChannel)
: null,
subchannel_ref: event.childSubchannel
? subchannelRefToMessage(event.childSubchannel)
: null,
};
}),
};
}
}
type RefOrderedMap = OrderedMap<
number,
{ ref: { id: number; kind: EntityTypes; name: string }; count: number }
>;
export class ChannelzChildrenTracker {
private channelChildren: RefOrderedMap = new OrderedMap();
private subchannelChildren: RefOrderedMap = new OrderedMap();
private socketChildren: RefOrderedMap = new OrderedMap();
private trackerMap = {
[EntityTypes.channel]: this.channelChildren,
[EntityTypes.subchannel]: this.subchannelChildren,
[EntityTypes.socket]: this.socketChildren,
} as const;
refChild(child: ChannelRef | SubchannelRef | SocketRef) {
const tracker = this.trackerMap[child.kind];
const trackedChild = tracker.find(child.id);
if (trackedChild.equals(tracker.end())) {
tracker.setElement(
child.id,
{
ref: child,
count: 1,
},
trackedChild
);
} else {
trackedChild.pointer[1].count += 1;
}
}
unrefChild(child: ChannelRef | SubchannelRef | SocketRef) {
const tracker = this.trackerMap[child.kind];
const trackedChild = tracker.getElementByKey(child.id);
if (trackedChild !== undefined) {
trackedChild.count -= 1;
if (trackedChild.count === 0) {
tracker.eraseElementByKey(child.id);
}
}
}
getChildLists(): ChannelzChildren {
return {
channels: this.channelChildren as ChannelzChildren['channels'],
subchannels: this.subchannelChildren as ChannelzChildren['subchannels'],
sockets: this.socketChildren as ChannelzChildren['sockets'],
};
}
}
export class ChannelzChildrenTrackerStub extends ChannelzChildrenTracker {
override refChild(): void {}
override unrefChild(): void {}
}
export class ChannelzCallTracker {
callsStarted = 0;
callsSucceeded = 0;
callsFailed = 0;
lastCallStartedTimestamp: Date | null = null;
addCallStarted() {
this.callsStarted += 1;
this.lastCallStartedTimestamp = new Date();
}
addCallSucceeded() {
this.callsSucceeded += 1;
}
addCallFailed() {
this.callsFailed += 1;
}
}
export class ChannelzCallTrackerStub extends ChannelzCallTracker {
override addCallStarted() {}
override addCallSucceeded() {}
override addCallFailed() {}
}
export interface ChannelzChildren {
channels: OrderedMap<number, { ref: ChannelRef; count: number }>;
subchannels: OrderedMap<number, { ref: SubchannelRef; count: number }>;
sockets: OrderedMap<number, { ref: SocketRef; count: number }>;
}
export interface ChannelInfo {
target: string;
state: ConnectivityState;
trace: ChannelzTrace | ChannelzTraceStub;
callTracker: ChannelzCallTracker | ChannelzCallTrackerStub;
children: ChannelzChildren;
}
export type SubchannelInfo = ChannelInfo;
export interface ServerInfo {
trace: ChannelzTrace;
callTracker: ChannelzCallTracker;
listenerChildren: ChannelzChildren;
sessionChildren: ChannelzChildren;
}
export interface TlsInfo {
cipherSuiteStandardName: string | null;
cipherSuiteOtherName: string | null;
localCertificate: Buffer | null;
remoteCertificate: Buffer | null;
}
export interface SocketInfo {
localAddress: SubchannelAddress | null;
remoteAddress: SubchannelAddress | null;
security: TlsInfo | null;
remoteName: string | null;
streamsStarted: number;
streamsSucceeded: number;
streamsFailed: number;
messagesSent: number;
messagesReceived: number;
keepAlivesSent: number;
lastLocalStreamCreatedTimestamp: Date | null;
lastRemoteStreamCreatedTimestamp: Date | null;
lastMessageSentTimestamp: Date | null;
lastMessageReceivedTimestamp: Date | null;
localFlowControlWindow: number | null;
remoteFlowControlWindow: number | null;
}
interface ChannelEntry {
ref: ChannelRef;
getInfo(): ChannelInfo;
}
interface SubchannelEntry {
ref: SubchannelRef;
getInfo(): SubchannelInfo;
}
interface ServerEntry {
ref: ServerRef;
getInfo(): ServerInfo;
}
interface SocketEntry {
ref: SocketRef;
getInfo(): SocketInfo;
}
export const enum EntityTypes {
channel = 'channel',
subchannel = 'subchannel',
server = 'server',
socket = 'socket',
}
type EntryOrderedMap = OrderedMap<number, { ref: Ref; getInfo: () => any }>;
const entityMaps = {
[EntityTypes.channel]: new OrderedMap<number, ChannelEntry>(),
[EntityTypes.subchannel]: new OrderedMap<number, SubchannelEntry>(),
[EntityTypes.server]: new OrderedMap<number, ServerEntry>(),
[EntityTypes.socket]: new OrderedMap<number, SocketEntry>(),
} as const;
export type RefByType<T extends EntityTypes> = T extends EntityTypes.channel
? ChannelRef
: T extends EntityTypes.server
? ServerRef
: T extends EntityTypes.socket
? SocketRef
: T extends EntityTypes.subchannel
? SubchannelRef
: never;
export type EntryByType<T extends EntityTypes> = T extends EntityTypes.channel
? ChannelEntry
: T extends EntityTypes.server
? ServerEntry
: T extends EntityTypes.socket
? SocketEntry
: T extends EntityTypes.subchannel
? SubchannelEntry
: never;
export type InfoByType<T extends EntityTypes> = T extends EntityTypes.channel
? ChannelInfo
: T extends EntityTypes.subchannel
? SubchannelInfo
: T extends EntityTypes.server
? ServerInfo
: T extends EntityTypes.socket
? SocketInfo
: never;
const generateRegisterFn = <R extends EntityTypes>(kind: R) => {
let nextId = 1;
function getNextId(): number {
return nextId++;
}
const entityMap: EntryOrderedMap = entityMaps[kind];
return (
name: string,
getInfo: () => InfoByType<R>,
channelzEnabled: boolean
): RefByType<R> => {
const id = getNextId();
const ref = { id, name, kind } as RefByType<R>;
if (channelzEnabled) {
entityMap.setElement(id, { ref, getInfo });
}
return ref;
};
};
export const registerChannelzChannel = generateRegisterFn(EntityTypes.channel);
export const registerChannelzSubchannel = generateRegisterFn(
EntityTypes.subchannel
);
export const registerChannelzServer = generateRegisterFn(EntityTypes.server);
export const registerChannelzSocket = generateRegisterFn(EntityTypes.socket);
export function unregisterChannelzRef(
ref: ChannelRef | SubchannelRef | ServerRef | SocketRef
) {
entityMaps[ref.kind].eraseElementByKey(ref.id);
}
/**
* Parse a single section of an IPv6 address as two bytes
* @param addressSection A hexadecimal string of length up to 4
* @returns The pair of bytes representing this address section
*/
function parseIPv6Section(addressSection: string): [number, number] {
const numberValue = Number.parseInt(addressSection, 16);
return [(numberValue / 256) | 0, numberValue % 256];
}
/**
* Parse a chunk of an IPv6 address string to some number of bytes
* @param addressChunk Some number of segments of up to 4 hexadecimal
* characters each, joined by colons.
* @returns The list of bytes representing this address chunk
*/
function parseIPv6Chunk(addressChunk: string): number[] {
if (addressChunk === '') {
return [];
}
const bytePairs = addressChunk
.split(':')
.map(section => parseIPv6Section(section));
const result: number[] = [];
return result.concat(...bytePairs);
}
function isIPv6MappedIPv4(ipAddress: string) {
return isIPv6(ipAddress) && ipAddress.toLowerCase().startsWith('::ffff:') && isIPv4(ipAddress.substring(7));
}
/**
* Prerequisite: isIPv4(ipAddress)
* @param ipAddress
* @returns
*/
function ipv4AddressStringToBuffer(ipAddress: string): Buffer {
return Buffer.from(
Uint8Array.from(
ipAddress.split('.').map(segment => Number.parseInt(segment))
)
);
}
/**
* Converts an IPv4 or IPv6 address from string representation to binary
* representation
* @param ipAddress an IP address in standard IPv4 or IPv6 text format
* @returns
*/
function ipAddressStringToBuffer(ipAddress: string): Buffer | null {
if (isIPv4(ipAddress)) {
return ipv4AddressStringToBuffer(ipAddress);
} else if (isIPv6MappedIPv4(ipAddress)) {
return ipv4AddressStringToBuffer(ipAddress.substring(7));
} else if (isIPv6(ipAddress)) {
let leftSection: string;
let rightSection: string;
const doubleColonIndex = ipAddress.indexOf('::');
if (doubleColonIndex === -1) {
leftSection = ipAddress;
rightSection = '';
} else {
leftSection = ipAddress.substring(0, doubleColonIndex);
rightSection = ipAddress.substring(doubleColonIndex + 2);
}
const leftBuffer = Buffer.from(parseIPv6Chunk(leftSection));
const rightBuffer = Buffer.from(parseIPv6Chunk(rightSection));
const middleBuffer = Buffer.alloc(
16 - leftBuffer.length - rightBuffer.length,
0
);
return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]);
} else {
return null;
}
}
function connectivityStateToMessage(
state: ConnectivityState
): ChannelConnectivityState__Output {
switch (state) {
case ConnectivityState.CONNECTING:
return {
state: 'CONNECTING',
};
case ConnectivityState.IDLE:
return {
state: 'IDLE',
};
case ConnectivityState.READY:
return {
state: 'READY',
};
case ConnectivityState.SHUTDOWN:
return {
state: 'SHUTDOWN',
};
case ConnectivityState.TRANSIENT_FAILURE:
return {
state: 'TRANSIENT_FAILURE',
};
default:
return {
state: 'UNKNOWN',
};
}
}
function dateToProtoTimestamp(date?: Date | null): Timestamp | null {
if (!date) {
return null;
}
const millisSinceEpoch = date.getTime();
return {
seconds: (millisSinceEpoch / 1000) | 0,
nanos: (millisSinceEpoch % 1000) * 1_000_000,
};
}
function getChannelMessage(channelEntry: ChannelEntry): ChannelMessage {
const resolvedInfo = channelEntry.getInfo();
const channelRef: ChannelRefMessage[] = [];
const subchannelRef: SubchannelRefMessage[] = [];
resolvedInfo.children.channels.forEach(el => {
channelRef.push(channelRefToMessage(el[1].ref));
});
resolvedInfo.children.subchannels.forEach(el => {
subchannelRef.push(subchannelRefToMessage(el[1].ref));
});
return {
ref: channelRefToMessage(channelEntry.ref),
data: {
target: resolvedInfo.target,
state: connectivityStateToMessage(resolvedInfo.state),
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(
resolvedInfo.callTracker.lastCallStartedTimestamp
),
trace: resolvedInfo.trace.getTraceMessage(),
},
channel_ref: channelRef,
subchannel_ref: subchannelRef,
};
}
function GetChannel(
call: ServerUnaryCall<GetChannelRequest__Output, GetChannelResponse>,
callback: sendUnaryData<GetChannelResponse>
): void {
const channelId = parseInt(call.request.channel_id, 10);
const channelEntry =
entityMaps[EntityTypes.channel].getElementByKey(channelId);
if (channelEntry === undefined) {
callback({
code: Status.NOT_FOUND,
details: 'No channel data found for id ' + channelId,
});
return;
}
callback(null, { channel: getChannelMessage(channelEntry) });
}
function GetTopChannels(
call: ServerUnaryCall<GetTopChannelsRequest__Output, GetTopChannelsResponse>,
callback: sendUnaryData<GetTopChannelsResponse>
): void {
const maxResults =
parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
const resultList: ChannelMessage[] = [];
const startId = parseInt(call.request.start_channel_id, 10);
const channelEntries = entityMaps[EntityTypes.channel];
let i: OrderedMapIterator<number, ChannelEntry>;
for (
i = channelEntries.lowerBound(startId);
!i.equals(channelEntries.end()) && resultList.length < maxResults;
i = i.next()
) {
resultList.push(getChannelMessage(i.pointer[1]));
}
callback(null, {
channel: resultList,
end: i.equals(channelEntries.end()),
});
}
function getServerMessage(serverEntry: ServerEntry): ServerMessage {
const resolvedInfo = serverEntry.getInfo();
const listenSocket: SocketRefMessage[] = [];
resolvedInfo.listenerChildren.sockets.forEach(el => {
listenSocket.push(socketRefToMessage(el[1].ref));
});
return {
ref: serverRefToMessage(serverEntry.ref),
data: {
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(
resolvedInfo.callTracker.lastCallStartedTimestamp
),
trace: resolvedInfo.trace.getTraceMessage(),
},
listen_socket: listenSocket,
};
}
function GetServer(
call: ServerUnaryCall<GetServerRequest__Output, GetServerResponse>,
callback: sendUnaryData<GetServerResponse>
): void {
const serverId = parseInt(call.request.server_id, 10);
const serverEntries = entityMaps[EntityTypes.server];
const serverEntry = serverEntries.getElementByKey(serverId);
if (serverEntry === undefined) {
callback({
code: Status.NOT_FOUND,
details: 'No server data found for id ' + serverId,
});
return;
}
callback(null, { server: getServerMessage(serverEntry) });
}
function GetServers(
call: ServerUnaryCall<GetServersRequest__Output, GetServersResponse>,
callback: sendUnaryData<GetServersResponse>
): void {
const maxResults =
parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
const startId = parseInt(call.request.start_server_id, 10);
const serverEntries = entityMaps[EntityTypes.server];
const resultList: ServerMessage[] = [];
let i: OrderedMapIterator<number, ServerEntry>;
for (
i = serverEntries.lowerBound(startId);
!i.equals(serverEntries.end()) && resultList.length < maxResults;
i = i.next()
) {
resultList.push(getServerMessage(i.pointer[1]));
}
callback(null, {
server: resultList,
end: i.equals(serverEntries.end()),
});
}
function GetSubchannel(
call: ServerUnaryCall<GetSubchannelRequest__Output, GetSubchannelResponse>,
callback: sendUnaryData<GetSubchannelResponse>
): void {
const subchannelId = parseInt(call.request.subchannel_id, 10);
const subchannelEntry =
entityMaps[EntityTypes.subchannel].getElementByKey(subchannelId);
if (subchannelEntry === undefined) {
callback({
code: Status.NOT_FOUND,
details: 'No subchannel data found for id ' + subchannelId,
});
return;
}
const resolvedInfo = subchannelEntry.getInfo();
const listenSocket: SocketRefMessage[] = [];
resolvedInfo.children.sockets.forEach(el => {
listenSocket.push(socketRefToMessage(el[1].ref));
});
const subchannelMessage: SubchannelMessage = {
ref: subchannelRefToMessage(subchannelEntry.ref),
data: {
target: resolvedInfo.target,
state: connectivityStateToMessage(resolvedInfo.state),
calls_started: resolvedInfo.callTracker.callsStarted,
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
calls_failed: resolvedInfo.callTracker.callsFailed,
last_call_started_timestamp: dateToProtoTimestamp(
resolvedInfo.callTracker.lastCallStartedTimestamp
),
trace: resolvedInfo.trace.getTraceMessage(),
},
socket_ref: listenSocket,
};
callback(null, { subchannel: subchannelMessage });
}
function subchannelAddressToAddressMessage(
subchannelAddress: SubchannelAddress
): Address {
if (isTcpSubchannelAddress(subchannelAddress)) {
return {
address: 'tcpip_address',
tcpip_address: {
ip_address:
ipAddressStringToBuffer(subchannelAddress.host) ?? undefined,
port: subchannelAddress.port,
},
};
} else {
return {
address: 'uds_address',
uds_address: {
filename: subchannelAddress.path,
},
};
}
}
function GetSocket(
call: ServerUnaryCall<GetSocketRequest__Output, GetSocketResponse>,
callback: sendUnaryData<GetSocketResponse>
): void {
const socketId = parseInt(call.request.socket_id, 10);
const socketEntry = entityMaps[EntityTypes.socket].getElementByKey(socketId);
if (socketEntry === undefined) {
callback({
code: Status.NOT_FOUND,
details: 'No socket data found for id ' + socketId,
});
return;
}
const resolvedInfo = socketEntry.getInfo();
const securityMessage: Security | null = resolvedInfo.security
? {
model: 'tls',
tls: {
cipher_suite: resolvedInfo.security.cipherSuiteStandardName
? 'standard_name'
: 'other_name',
standard_name:
resolvedInfo.security.cipherSuiteStandardName ?? undefined,
other_name: resolvedInfo.security.cipherSuiteOtherName ?? undefined,
local_certificate:
resolvedInfo.security.localCertificate ?? undefined,
remote_certificate:
resolvedInfo.security.remoteCertificate ?? undefined,
},
}
: null;
const socketMessage: SocketMessage = {
ref: socketRefToMessage(socketEntry.ref),
local: resolvedInfo.localAddress
? subchannelAddressToAddressMessage(resolvedInfo.localAddress)
: null,
remote: resolvedInfo.remoteAddress
? subchannelAddressToAddressMessage(resolvedInfo.remoteAddress)
: null,
remote_name: resolvedInfo.remoteName ?? undefined,
security: securityMessage,
data: {
keep_alives_sent: resolvedInfo.keepAlivesSent,
streams_started: resolvedInfo.streamsStarted,
streams_succeeded: resolvedInfo.streamsSucceeded,
streams_failed: resolvedInfo.streamsFailed,
last_local_stream_created_timestamp: dateToProtoTimestamp(
resolvedInfo.lastLocalStreamCreatedTimestamp
),
last_remote_stream_created_timestamp: dateToProtoTimestamp(
resolvedInfo.lastRemoteStreamCreatedTimestamp
),
messages_received: resolvedInfo.messagesReceived,
messages_sent: resolvedInfo.messagesSent,
last_message_received_timestamp: dateToProtoTimestamp(
resolvedInfo.lastMessageReceivedTimestamp
),
last_message_sent_timestamp: dateToProtoTimestamp(
resolvedInfo.lastMessageSentTimestamp
),
local_flow_control_window: resolvedInfo.localFlowControlWindow
? { value: resolvedInfo.localFlowControlWindow }
: null,
remote_flow_control_window: resolvedInfo.remoteFlowControlWindow
? { value: resolvedInfo.remoteFlowControlWindow }
: null,
},
};
callback(null, { socket: socketMessage });
}
function GetServerSockets(
call: ServerUnaryCall<
GetServerSocketsRequest__Output,
GetServerSocketsResponse
>,
callback: sendUnaryData<GetServerSocketsResponse>
): void {
const serverId = parseInt(call.request.server_id, 10);
const serverEntry = entityMaps[EntityTypes.server].getElementByKey(serverId);
if (serverEntry === undefined) {
callback({
code: Status.NOT_FOUND,
details: 'No server data found for id ' + serverId,
});
return;
}
const startId = parseInt(call.request.start_socket_id, 10);
const maxResults =
parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
const resolvedInfo = serverEntry.getInfo();
// If we wanted to include listener sockets in the result, this line would
// instead say
// const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id);
const allSockets = resolvedInfo.sessionChildren.sockets;
const resultList: SocketRefMessage[] = [];
let i: OrderedMapIterator<number, { ref: SocketRef }>;
for (
i = allSockets.lowerBound(startId);
!i.equals(allSockets.end()) && resultList.length < maxResults;
i = i.next()
) {
resultList.push(socketRefToMessage(i.pointer[1].ref));
}
callback(null, {
socket_ref: resultList,
end: i.equals(allSockets.end()),
});
}
export function getChannelzHandlers(): ChannelzHandlers {
return {
GetChannel,
GetTopChannels,
GetServer,
GetServers,
GetSubchannel,
GetSocket,
GetServerSockets,
};
}
let loadedChannelzDefinition: ChannelzDefinition | null = null;
export function getChannelzServiceDefinition(): ChannelzDefinition {
if (loadedChannelzDefinition) {
return loadedChannelzDefinition;
}
/* The purpose of this complexity is to avoid loading @grpc/proto-loader at
* runtime for users who will not use/enable channelz. */
const loaderLoadSync = require('@grpc/proto-loader')
.loadSync as typeof loadSync;
const loadedProto = loaderLoadSync('channelz.proto', {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [`${__dirname}/../../proto`],
});
const channelzGrpcObject = loadPackageDefinition(
loadedProto
) as unknown as ChannelzProtoGrpcType;
loadedChannelzDefinition =
channelzGrpcObject.grpc.channelz.v1.Channelz.service;
return loadedChannelzDefinition;
}
export function setup() {
registerAdminService(getChannelzServiceDefinition, getChannelzHandlers);
}

View File

@@ -0,0 +1,585 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { Metadata } from './metadata';
import {
StatusObject,
Listener,
MetadataListener,
MessageListener,
StatusListener,
FullListener,
InterceptingListener,
InterceptingListenerImpl,
isInterceptingListener,
MessageContext,
Call,
} from './call-interface';
import { Status } from './constants';
import { Channel } from './channel';
import { CallOptions } from './client';
import { ClientMethodDefinition } from './make-client';
import { getErrorMessage } from './error';
import { AuthContext } from './auth-context';
/**
* Error class associated with passing both interceptors and interceptor
* providers to a client constructor or as call options.
*/
export class InterceptorConfigurationError extends Error {
constructor(message: string) {
super(message);
this.name = 'InterceptorConfigurationError';
Error.captureStackTrace(this, InterceptorConfigurationError);
}
}
export interface MetadataRequester {
(
metadata: Metadata,
listener: InterceptingListener,
next: (
metadata: Metadata,
listener: InterceptingListener | Listener
) => void
): void;
}
export interface MessageRequester {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(message: any, next: (message: any) => void): void;
}
export interface CloseRequester {
(next: () => void): void;
}
export interface CancelRequester {
(next: () => void): void;
}
/**
* An object with methods for intercepting and modifying outgoing call operations.
*/
export interface FullRequester {
start: MetadataRequester;
sendMessage: MessageRequester;
halfClose: CloseRequester;
cancel: CancelRequester;
}
export type Requester = Partial<FullRequester>;
export class ListenerBuilder {
private metadata: MetadataListener | undefined = undefined;
private message: MessageListener | undefined = undefined;
private status: StatusListener | undefined = undefined;
withOnReceiveMetadata(onReceiveMetadata: MetadataListener): this {
this.metadata = onReceiveMetadata;
return this;
}
withOnReceiveMessage(onReceiveMessage: MessageListener): this {
this.message = onReceiveMessage;
return this;
}
withOnReceiveStatus(onReceiveStatus: StatusListener): this {
this.status = onReceiveStatus;
return this;
}
build(): Listener {
return {
onReceiveMetadata: this.metadata,
onReceiveMessage: this.message,
onReceiveStatus: this.status,
};
}
}
export class RequesterBuilder {
private start: MetadataRequester | undefined = undefined;
private message: MessageRequester | undefined = undefined;
private halfClose: CloseRequester | undefined = undefined;
private cancel: CancelRequester | undefined = undefined;
withStart(start: MetadataRequester): this {
this.start = start;
return this;
}
withSendMessage(sendMessage: MessageRequester): this {
this.message = sendMessage;
return this;
}
withHalfClose(halfClose: CloseRequester): this {
this.halfClose = halfClose;
return this;
}
withCancel(cancel: CancelRequester): this {
this.cancel = cancel;
return this;
}
build(): Requester {
return {
start: this.start,
sendMessage: this.message,
halfClose: this.halfClose,
cancel: this.cancel,
};
}
}
/**
* A Listener with a default pass-through implementation of each method. Used
* for filling out Listeners with some methods omitted.
*/
const defaultListener: FullListener = {
onReceiveMetadata: (metadata, next) => {
next(metadata);
},
onReceiveMessage: (message, next) => {
next(message);
},
onReceiveStatus: (status, next) => {
next(status);
},
};
/**
* A Requester with a default pass-through implementation of each method. Used
* for filling out Requesters with some methods omitted.
*/
const defaultRequester: FullRequester = {
start: (metadata, listener, next) => {
next(metadata, listener);
},
sendMessage: (message, next) => {
next(message);
},
halfClose: next => {
next();
},
cancel: next => {
next();
},
};
export interface InterceptorOptions extends CallOptions {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
method_definition: ClientMethodDefinition<any, any>;
}
export interface InterceptingCallInterface {
cancelWithStatus(status: Status, details: string): void;
getPeer(): string;
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessageWithContext(context: MessageContext, message: any): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessage(message: any): void;
startRead(): void;
halfClose(): void;
getAuthContext(): AuthContext | null;
}
export class InterceptingCall implements InterceptingCallInterface {
/**
* The requester that this InterceptingCall uses to modify outgoing operations
*/
private requester: FullRequester;
/**
* Indicates that metadata has been passed to the requester's start
* method but it has not been passed to the corresponding next callback
*/
private processingMetadata = false;
/**
* Message context for a pending message that is waiting for
*/
private pendingMessageContext: MessageContext | null = null;
private pendingMessage: any;
/**
* Indicates that a message has been passed to the requester's sendMessage
* method but it has not been passed to the corresponding next callback
*/
private processingMessage = false;
/**
* Indicates that a status was received but could not be propagated because
* a message was still being processed.
*/
private pendingHalfClose = false;
constructor(
private nextCall: InterceptingCallInterface,
requester?: Requester
) {
if (requester) {
this.requester = {
start: requester.start ?? defaultRequester.start,
sendMessage: requester.sendMessage ?? defaultRequester.sendMessage,
halfClose: requester.halfClose ?? defaultRequester.halfClose,
cancel: requester.cancel ?? defaultRequester.cancel,
};
} else {
this.requester = defaultRequester;
}
}
cancelWithStatus(status: Status, details: string) {
this.requester.cancel(() => {
this.nextCall.cancelWithStatus(status, details);
});
}
getPeer() {
return this.nextCall.getPeer();
}
private processPendingMessage() {
if (this.pendingMessageContext) {
this.nextCall.sendMessageWithContext(
this.pendingMessageContext,
this.pendingMessage
);
this.pendingMessageContext = null;
this.pendingMessage = null;
}
}
private processPendingHalfClose() {
if (this.pendingHalfClose) {
this.nextCall.halfClose();
}
}
start(
metadata: Metadata,
interceptingListener?: Partial<InterceptingListener>
): void {
const fullInterceptingListener: InterceptingListener = {
onReceiveMetadata:
interceptingListener?.onReceiveMetadata?.bind(interceptingListener) ??
(metadata => {}),
onReceiveMessage:
interceptingListener?.onReceiveMessage?.bind(interceptingListener) ??
(message => {}),
onReceiveStatus:
interceptingListener?.onReceiveStatus?.bind(interceptingListener) ??
(status => {}),
};
this.processingMetadata = true;
this.requester.start(metadata, fullInterceptingListener, (md, listener) => {
this.processingMetadata = false;
let finalInterceptingListener: InterceptingListener;
if (isInterceptingListener(listener)) {
finalInterceptingListener = listener;
} else {
const fullListener: FullListener = {
onReceiveMetadata:
listener.onReceiveMetadata ?? defaultListener.onReceiveMetadata,
onReceiveMessage:
listener.onReceiveMessage ?? defaultListener.onReceiveMessage,
onReceiveStatus:
listener.onReceiveStatus ?? defaultListener.onReceiveStatus,
};
finalInterceptingListener = new InterceptingListenerImpl(
fullListener,
fullInterceptingListener
);
}
this.nextCall.start(md, finalInterceptingListener);
this.processPendingMessage();
this.processPendingHalfClose();
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessageWithContext(context: MessageContext, message: any): void {
this.processingMessage = true;
this.requester.sendMessage(message, finalMessage => {
this.processingMessage = false;
if (this.processingMetadata) {
this.pendingMessageContext = context;
this.pendingMessage = message;
} else {
this.nextCall.sendMessageWithContext(context, finalMessage);
this.processPendingHalfClose();
}
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessage(message: any): void {
this.sendMessageWithContext({}, message);
}
startRead(): void {
this.nextCall.startRead();
}
halfClose(): void {
this.requester.halfClose(() => {
if (this.processingMetadata || this.processingMessage) {
this.pendingHalfClose = true;
} else {
this.nextCall.halfClose();
}
});
}
getAuthContext(): AuthContext | null {
return this.nextCall.getAuthContext();
}
}
function getCall(channel: Channel, path: string, options: CallOptions): Call {
const deadline = options.deadline ?? Infinity;
const host = options.host;
const parent = options.parent ?? null;
const propagateFlags = options.propagate_flags;
const credentials = options.credentials;
const call = channel.createCall(path, deadline, host, parent, propagateFlags);
if (credentials) {
call.setCredentials(credentials);
}
return call;
}
/**
* InterceptingCall implementation that directly owns the underlying Call
* object and handles serialization and deseraizliation.
*/
class BaseInterceptingCall implements InterceptingCallInterface {
constructor(
protected call: Call,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
protected methodDefinition: ClientMethodDefinition<any, any>
) {}
cancelWithStatus(status: Status, details: string): void {
this.call.cancelWithStatus(status, details);
}
getPeer(): string {
return this.call.getPeer();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessageWithContext(context: MessageContext, message: any): void {
let serialized: Buffer;
try {
serialized = this.methodDefinition.requestSerialize(message);
} catch (e) {
this.call.cancelWithStatus(
Status.INTERNAL,
`Request message serialization failure: ${getErrorMessage(e)}`
);
return;
}
this.call.sendMessageWithContext(context, serialized);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sendMessage(message: any) {
this.sendMessageWithContext({}, message);
}
start(
metadata: Metadata,
interceptingListener?: Partial<InterceptingListener>
): void {
let readError: StatusObject | null = null;
this.call.start(metadata, {
onReceiveMetadata: metadata => {
interceptingListener?.onReceiveMetadata?.(metadata);
},
onReceiveMessage: message => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let deserialized: any;
try {
deserialized = this.methodDefinition.responseDeserialize(message);
} catch (e) {
readError = {
code: Status.INTERNAL,
details: `Response message parsing error: ${getErrorMessage(e)}`,
metadata: new Metadata(),
};
this.call.cancelWithStatus(readError.code, readError.details);
return;
}
interceptingListener?.onReceiveMessage?.(deserialized);
},
onReceiveStatus: status => {
if (readError) {
interceptingListener?.onReceiveStatus?.(readError);
} else {
interceptingListener?.onReceiveStatus?.(status);
}
},
});
}
startRead() {
this.call.startRead();
}
halfClose(): void {
this.call.halfClose();
}
getAuthContext(): AuthContext | null {
return this.call.getAuthContext();
}
}
/**
* BaseInterceptingCall with special-cased behavior for methods with unary
* responses.
*/
class BaseUnaryInterceptingCall
extends BaseInterceptingCall
implements InterceptingCallInterface
{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(call: Call, methodDefinition: ClientMethodDefinition<any, any>) {
super(call, methodDefinition);
}
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void {
let receivedMessage = false;
const wrapperListener: InterceptingListener = {
onReceiveMetadata:
listener?.onReceiveMetadata?.bind(listener) ?? (metadata => {}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage: (message: any) => {
receivedMessage = true;
listener?.onReceiveMessage?.(message);
},
onReceiveStatus: (status: StatusObject) => {
if (!receivedMessage) {
listener?.onReceiveMessage?.(null);
}
listener?.onReceiveStatus?.(status);
},
};
super.start(metadata, wrapperListener);
this.call.startRead();
}
}
/**
* BaseInterceptingCall with special-cased behavior for methods with streaming
* responses.
*/
class BaseStreamingInterceptingCall
extends BaseInterceptingCall
implements InterceptingCallInterface {}
function getBottomInterceptingCall(
channel: Channel,
options: InterceptorOptions,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
methodDefinition: ClientMethodDefinition<any, any>
) {
const call = getCall(channel, methodDefinition.path, options);
if (methodDefinition.responseStream) {
return new BaseStreamingInterceptingCall(call, methodDefinition);
} else {
return new BaseUnaryInterceptingCall(call, methodDefinition);
}
}
export interface NextCall {
(options: InterceptorOptions): InterceptingCallInterface;
}
export interface Interceptor {
(options: InterceptorOptions, nextCall: NextCall): InterceptingCall;
}
export interface InterceptorProvider {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(methodDefinition: ClientMethodDefinition<any, any>): Interceptor;
}
export interface InterceptorArguments {
clientInterceptors: Interceptor[];
clientInterceptorProviders: InterceptorProvider[];
callInterceptors: Interceptor[];
callInterceptorProviders: InterceptorProvider[];
}
export function getInterceptingCall(
interceptorArgs: InterceptorArguments,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
methodDefinition: ClientMethodDefinition<any, any>,
options: CallOptions,
channel: Channel
): InterceptingCallInterface {
if (
interceptorArgs.clientInterceptors.length > 0 &&
interceptorArgs.clientInterceptorProviders.length > 0
) {
throw new InterceptorConfigurationError(
'Both interceptors and interceptor_providers were passed as options ' +
'to the client constructor. Only one of these is allowed.'
);
}
if (
interceptorArgs.callInterceptors.length > 0 &&
interceptorArgs.callInterceptorProviders.length > 0
) {
throw new InterceptorConfigurationError(
'Both interceptors and interceptor_providers were passed as call ' +
'options. Only one of these is allowed.'
);
}
let interceptors: Interceptor[] = [];
// Interceptors passed to the call override interceptors passed to the client constructor
if (
interceptorArgs.callInterceptors.length > 0 ||
interceptorArgs.callInterceptorProviders.length > 0
) {
interceptors = ([] as Interceptor[])
.concat(
interceptorArgs.callInterceptors,
interceptorArgs.callInterceptorProviders.map(provider =>
provider(methodDefinition)
)
)
.filter(interceptor => interceptor);
// Filter out falsy values when providers return nothing
} else {
interceptors = ([] as Interceptor[])
.concat(
interceptorArgs.clientInterceptors,
interceptorArgs.clientInterceptorProviders.map(provider =>
provider(methodDefinition)
)
)
.filter(interceptor => interceptor);
// Filter out falsy values when providers return nothing
}
const interceptorOptions = Object.assign({}, options, {
method_definition: methodDefinition,
});
/* For each interceptor in the list, the nextCall function passed to it is
* based on the next interceptor in the list, using a nextCall function
* constructed with the following interceptor in the list, and so on. The
* initialValue, which is effectively at the end of the list, is a nextCall
* function that invokes getBottomInterceptingCall, the result of which
* handles (de)serialization and also gets the underlying call from the
* channel. */
const getCall: NextCall = interceptors.reduceRight<NextCall>(
(nextCall: NextCall, nextInterceptor: Interceptor) => {
return currentOptions => nextInterceptor(currentOptions, nextCall);
},
(finalOptions: InterceptorOptions) =>
getBottomInterceptingCall(channel, finalOptions, methodDefinition)
);
return getCall(interceptorOptions);
}

View File

@@ -0,0 +1,716 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import {
ClientDuplexStream,
ClientDuplexStreamImpl,
ClientReadableStream,
ClientReadableStreamImpl,
ClientUnaryCall,
ClientUnaryCallImpl,
ClientWritableStream,
ClientWritableStreamImpl,
ServiceError,
callErrorFromStatus,
SurfaceCall,
} from './call';
import { CallCredentials } from './call-credentials';
import { StatusObject } from './call-interface';
import { Channel, ChannelImplementation } from './channel';
import { ConnectivityState } from './connectivity-state';
import { ChannelCredentials } from './channel-credentials';
import { ChannelOptions } from './channel-options';
import { Status } from './constants';
import { Metadata } from './metadata';
import { ClientMethodDefinition } from './make-client';
import {
getInterceptingCall,
Interceptor,
InterceptorProvider,
InterceptorArguments,
InterceptingCallInterface,
} from './client-interceptors';
import {
ServerUnaryCall,
ServerReadableStream,
ServerWritableStream,
ServerDuplexStream,
} from './server-call';
import { Deadline } from './deadline';
const CHANNEL_SYMBOL = Symbol();
const INTERCEPTOR_SYMBOL = Symbol();
const INTERCEPTOR_PROVIDER_SYMBOL = Symbol();
const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol();
function isFunction<ResponseType>(
arg: Metadata | CallOptions | UnaryCallback<ResponseType> | undefined
): arg is UnaryCallback<ResponseType> {
return typeof arg === 'function';
}
export interface UnaryCallback<ResponseType> {
(err: ServiceError | null, value?: ResponseType): void;
}
/* eslint-disable @typescript-eslint/no-explicit-any */
export interface CallOptions {
deadline?: Deadline;
host?: string;
parent?:
| ServerUnaryCall<any, any>
| ServerReadableStream<any, any>
| ServerWritableStream<any, any>
| ServerDuplexStream<any, any>;
propagate_flags?: number;
credentials?: CallCredentials;
interceptors?: Interceptor[];
interceptor_providers?: InterceptorProvider[];
}
/* eslint-enable @typescript-eslint/no-explicit-any */
export interface CallProperties<RequestType, ResponseType> {
argument?: RequestType;
metadata: Metadata;
call: SurfaceCall;
channel: Channel;
methodDefinition: ClientMethodDefinition<RequestType, ResponseType>;
callOptions: CallOptions;
callback?: UnaryCallback<ResponseType>;
}
export interface CallInvocationTransformer {
(callProperties: CallProperties<any, any>): CallProperties<any, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
}
export type ClientOptions = Partial<ChannelOptions> & {
channelOverride?: Channel;
channelFactoryOverride?: (
address: string,
credentials: ChannelCredentials,
options: ClientOptions
) => Channel;
interceptors?: Interceptor[];
interceptor_providers?: InterceptorProvider[];
callInvocationTransformer?: CallInvocationTransformer;
};
function getErrorStackString(error: Error): string {
return error.stack?.split('\n').slice(1).join('\n') || 'no stack trace available';
}
/**
* A generic gRPC client. Primarily useful as a base class for all generated
* clients.
*/
export class Client {
private readonly [CHANNEL_SYMBOL]: Channel;
private readonly [INTERCEPTOR_SYMBOL]: Interceptor[];
private readonly [INTERCEPTOR_PROVIDER_SYMBOL]: InterceptorProvider[];
private readonly [CALL_INVOCATION_TRANSFORMER_SYMBOL]?: CallInvocationTransformer;
constructor(
address: string,
credentials: ChannelCredentials,
options: ClientOptions = {}
) {
options = Object.assign({}, options);
this[INTERCEPTOR_SYMBOL] = options.interceptors ?? [];
delete options.interceptors;
this[INTERCEPTOR_PROVIDER_SYMBOL] = options.interceptor_providers ?? [];
delete options.interceptor_providers;
if (
this[INTERCEPTOR_SYMBOL].length > 0 &&
this[INTERCEPTOR_PROVIDER_SYMBOL].length > 0
) {
throw new Error(
'Both interceptors and interceptor_providers were passed as options ' +
'to the client constructor. Only one of these is allowed.'
);
}
this[CALL_INVOCATION_TRANSFORMER_SYMBOL] =
options.callInvocationTransformer;
delete options.callInvocationTransformer;
if (options.channelOverride) {
this[CHANNEL_SYMBOL] = options.channelOverride;
} else if (options.channelFactoryOverride) {
const channelFactoryOverride = options.channelFactoryOverride;
delete options.channelFactoryOverride;
this[CHANNEL_SYMBOL] = channelFactoryOverride(
address,
credentials,
options
);
} else {
this[CHANNEL_SYMBOL] = new ChannelImplementation(
address,
credentials,
options
);
}
}
close(): void {
this[CHANNEL_SYMBOL].close();
}
getChannel(): Channel {
return this[CHANNEL_SYMBOL];
}
waitForReady(deadline: Deadline, callback: (error?: Error) => void): void {
const checkState = (err?: Error) => {
if (err) {
callback(new Error('Failed to connect before the deadline'));
return;
}
let newState;
try {
newState = this[CHANNEL_SYMBOL].getConnectivityState(true);
} catch (e) {
callback(new Error('The channel has been closed'));
return;
}
if (newState === ConnectivityState.READY) {
callback();
} else {
try {
this[CHANNEL_SYMBOL].watchConnectivityState(
newState,
deadline,
checkState
);
} catch (e) {
callback(new Error('The channel has been closed'));
}
}
};
setImmediate(checkState);
}
private checkOptionalUnaryResponseArguments<ResponseType>(
arg1: Metadata | CallOptions | UnaryCallback<ResponseType>,
arg2?: CallOptions | UnaryCallback<ResponseType>,
arg3?: UnaryCallback<ResponseType>
): {
metadata: Metadata;
options: CallOptions;
callback: UnaryCallback<ResponseType>;
} {
if (isFunction(arg1)) {
return { metadata: new Metadata(), options: {}, callback: arg1 };
} else if (isFunction(arg2)) {
if (arg1 instanceof Metadata) {
return { metadata: arg1, options: {}, callback: arg2 };
} else {
return { metadata: new Metadata(), options: arg1, callback: arg2 };
}
} else {
if (
!(
arg1 instanceof Metadata &&
arg2 instanceof Object &&
isFunction(arg3)
)
) {
throw new Error('Incorrect arguments passed');
}
return { metadata: arg1, options: arg2, callback: arg3 };
}
}
makeUnaryRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
metadata: Metadata,
options: CallOptions,
callback: UnaryCallback<ResponseType>
): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
metadata: Metadata,
callback: UnaryCallback<ResponseType>
): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
options: CallOptions,
callback: UnaryCallback<ResponseType>
): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
callback: UnaryCallback<ResponseType>
): ClientUnaryCall;
makeUnaryRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
metadata: Metadata | CallOptions | UnaryCallback<ResponseType>,
options?: CallOptions | UnaryCallback<ResponseType>,
callback?: UnaryCallback<ResponseType>
): ClientUnaryCall {
const checkedArguments =
this.checkOptionalUnaryResponseArguments<ResponseType>(
metadata,
options,
callback
);
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
{
path: method,
requestStream: false,
responseStream: false,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties: CallProperties<RequestType, ResponseType> = {
argument: argument,
metadata: checkedArguments.metadata,
call: new ClientUnaryCallImpl(),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
callback: checkedArguments.callback,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
callProperties
) as CallProperties<RequestType, ResponseType>;
}
const emitter: ClientUnaryCall = callProperties.call;
const interceptorArgs: InterceptorArguments = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: callProperties.callOptions.interceptors ?? [],
callInterceptorProviders:
callProperties.callOptions.interceptor_providers ?? [],
};
const call: InterceptingCallInterface = getInterceptingCall(
interceptorArgs,
callProperties.methodDefinition,
callProperties.callOptions,
callProperties.channel
);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
emitter.call = call;
let responseMessage: ResponseType | null = null;
let receivedStatus = false;
let callerStackError: Error | null = new Error();
call.start(callProperties.metadata, {
onReceiveMetadata: metadata => {
emitter.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message: any) {
if (responseMessage !== null) {
call.cancelWithStatus(Status.UNIMPLEMENTED, 'Too many responses received');
}
responseMessage = message;
},
onReceiveStatus(status: StatusObject) {
if (receivedStatus) {
return;
}
receivedStatus = true;
if (status.code === Status.OK) {
if (responseMessage === null) {
const callerStack = getErrorStackString(callerStackError!);
callProperties.callback!(
callErrorFromStatus(
{
code: Status.UNIMPLEMENTED,
details: 'No message received',
metadata: status.metadata,
},
callerStack
)
);
} else {
callProperties.callback!(null, responseMessage);
}
} else {
const callerStack = getErrorStackString(callerStackError!);
callProperties.callback!(callErrorFromStatus(status, callerStack));
}
/* Avoid retaining the callerStackError object in the call context of
* the status event handler. */
callerStackError = null;
emitter.emit('status', status);
},
});
call.sendMessage(argument);
call.halfClose();
return emitter;
}
makeClientStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
metadata: Metadata,
options: CallOptions,
callback: UnaryCallback<ResponseType>
): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
metadata: Metadata,
callback: UnaryCallback<ResponseType>
): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
options: CallOptions,
callback: UnaryCallback<ResponseType>
): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
callback: UnaryCallback<ResponseType>
): ClientWritableStream<RequestType>;
makeClientStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
metadata: Metadata | CallOptions | UnaryCallback<ResponseType>,
options?: CallOptions | UnaryCallback<ResponseType>,
callback?: UnaryCallback<ResponseType>
): ClientWritableStream<RequestType> {
const checkedArguments =
this.checkOptionalUnaryResponseArguments<ResponseType>(
metadata,
options,
callback
);
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
{
path: method,
requestStream: true,
responseStream: false,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties: CallProperties<RequestType, ResponseType> = {
metadata: checkedArguments.metadata,
call: new ClientWritableStreamImpl<RequestType>(serialize),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
callback: checkedArguments.callback,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
callProperties
) as CallProperties<RequestType, ResponseType>;
}
const emitter: ClientWritableStream<RequestType> =
callProperties.call as ClientWritableStream<RequestType>;
const interceptorArgs: InterceptorArguments = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: callProperties.callOptions.interceptors ?? [],
callInterceptorProviders:
callProperties.callOptions.interceptor_providers ?? [],
};
const call: InterceptingCallInterface = getInterceptingCall(
interceptorArgs,
callProperties.methodDefinition,
callProperties.callOptions,
callProperties.channel
);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
emitter.call = call;
let responseMessage: ResponseType | null = null;
let receivedStatus = false;
let callerStackError: Error | null = new Error();
call.start(callProperties.metadata, {
onReceiveMetadata: metadata => {
emitter.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message: any) {
if (responseMessage !== null) {
call.cancelWithStatus(Status.UNIMPLEMENTED, 'Too many responses received');
}
responseMessage = message;
call.startRead();
},
onReceiveStatus(status: StatusObject) {
if (receivedStatus) {
return;
}
receivedStatus = true;
if (status.code === Status.OK) {
if (responseMessage === null) {
const callerStack = getErrorStackString(callerStackError!);
callProperties.callback!(
callErrorFromStatus(
{
code: Status.UNIMPLEMENTED,
details: 'No message received',
metadata: status.metadata,
},
callerStack
)
);
} else {
callProperties.callback!(null, responseMessage);
}
} else {
const callerStack = getErrorStackString(callerStackError!);
callProperties.callback!(callErrorFromStatus(status, callerStack));
}
/* Avoid retaining the callerStackError object in the call context of
* the status event handler. */
callerStackError = null;
emitter.emit('status', status);
},
});
return emitter;
}
private checkMetadataAndOptions(
arg1?: Metadata | CallOptions,
arg2?: CallOptions
): { metadata: Metadata; options: CallOptions } {
let metadata: Metadata;
let options: CallOptions;
if (arg1 instanceof Metadata) {
metadata = arg1;
if (arg2) {
options = arg2;
} else {
options = {};
}
} else {
if (arg1) {
options = arg1;
} else {
options = {};
}
metadata = new Metadata();
}
return { metadata, options };
}
makeServerStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
metadata: Metadata,
options?: CallOptions
): ClientReadableStream<ResponseType>;
makeServerStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
options?: CallOptions
): ClientReadableStream<ResponseType>;
makeServerStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
argument: RequestType,
metadata?: Metadata | CallOptions,
options?: CallOptions
): ClientReadableStream<ResponseType> {
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
{
path: method,
requestStream: false,
responseStream: true,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties: CallProperties<RequestType, ResponseType> = {
argument: argument,
metadata: checkedArguments.metadata,
call: new ClientReadableStreamImpl<ResponseType>(deserialize),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
callProperties
) as CallProperties<RequestType, ResponseType>;
}
const stream: ClientReadableStream<ResponseType> =
callProperties.call as ClientReadableStream<ResponseType>;
const interceptorArgs: InterceptorArguments = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: callProperties.callOptions.interceptors ?? [],
callInterceptorProviders:
callProperties.callOptions.interceptor_providers ?? [],
};
const call: InterceptingCallInterface = getInterceptingCall(
interceptorArgs,
callProperties.methodDefinition,
callProperties.callOptions,
callProperties.channel
);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
stream.call = call;
let receivedStatus = false;
let callerStackError: Error | null = new Error();
call.start(callProperties.metadata, {
onReceiveMetadata(metadata: Metadata) {
stream.emit('metadata', metadata);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onReceiveMessage(message: any) {
stream.push(message);
},
onReceiveStatus(status: StatusObject) {
if (receivedStatus) {
return;
}
receivedStatus = true;
stream.push(null);
if (status.code !== Status.OK) {
const callerStack = getErrorStackString(callerStackError!);
stream.emit('error', callErrorFromStatus(status, callerStack));
}
/* Avoid retaining the callerStackError object in the call context of
* the status event handler. */
callerStackError = null;
stream.emit('status', status);
},
});
call.sendMessage(argument);
call.halfClose();
return stream;
}
makeBidiStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
metadata: Metadata,
options?: CallOptions
): ClientDuplexStream<RequestType, ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
options?: CallOptions
): ClientDuplexStream<RequestType, ResponseType>;
makeBidiStreamRequest<RequestType, ResponseType>(
method: string,
serialize: (value: RequestType) => Buffer,
deserialize: (value: Buffer) => ResponseType,
metadata?: Metadata | CallOptions,
options?: CallOptions
): ClientDuplexStream<RequestType, ResponseType> {
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
{
path: method,
requestStream: true,
responseStream: true,
requestSerialize: serialize,
responseDeserialize: deserialize,
};
let callProperties: CallProperties<RequestType, ResponseType> = {
metadata: checkedArguments.metadata,
call: new ClientDuplexStreamImpl<RequestType, ResponseType>(
serialize,
deserialize
),
channel: this[CHANNEL_SYMBOL],
methodDefinition: methodDefinition,
callOptions: checkedArguments.options,
};
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
callProperties
) as CallProperties<RequestType, ResponseType>;
}
const stream: ClientDuplexStream<RequestType, ResponseType> =
callProperties.call as ClientDuplexStream<RequestType, ResponseType>;
const interceptorArgs: InterceptorArguments = {
clientInterceptors: this[INTERCEPTOR_SYMBOL],
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
callInterceptors: callProperties.callOptions.interceptors ?? [],
callInterceptorProviders:
callProperties.callOptions.interceptor_providers ?? [],
};
const call: InterceptingCallInterface = getInterceptingCall(
interceptorArgs,
callProperties.methodDefinition,
callProperties.callOptions,
callProperties.channel
);
/* This needs to happen before the emitter is used. Unfortunately we can't
* enforce this with the type system. We need to construct this emitter
* before calling the CallInvocationTransformer, and we need to create the
* call after that. */
stream.call = call;
let receivedStatus = false;
let callerStackError: Error | null = new Error();
call.start(callProperties.metadata, {
onReceiveMetadata(metadata: Metadata) {
stream.emit('metadata', metadata);
},
onReceiveMessage(message: Buffer) {
stream.push(message);
},
onReceiveStatus(status: StatusObject) {
if (receivedStatus) {
return;
}
receivedStatus = true;
stream.push(null);
if (status.code !== Status.OK) {
const callerStack = getErrorStackString(callerStackError!);
stream.emit('error', callErrorFromStatus(status, callerStack));
}
/* Avoid retaining the callerStackError object in the call context of
* the status event handler. */
callerStackError = null;
stream.emit('status', status);
},
});
return stream;
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export enum CompressionAlgorithms {
identity = 0,
deflate = 1,
gzip = 2,
}

View File

@@ -0,0 +1,358 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import * as zlib from 'zlib';
import { WriteObject, WriteFlags } from './call-interface';
import { Channel } from './channel';
import { ChannelOptions } from './channel-options';
import { CompressionAlgorithms } from './compression-algorithms';
import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, DEFAULT_MAX_SEND_MESSAGE_LENGTH, LogVerbosity, Status } from './constants';
import { BaseFilter, Filter, FilterFactory } from './filter';
import * as logging from './logging';
import { Metadata, MetadataValue } from './metadata';
const isCompressionAlgorithmKey = (
key: number
): key is CompressionAlgorithms => {
return (
typeof key === 'number' && typeof CompressionAlgorithms[key] === 'string'
);
};
type CompressionAlgorithm = keyof typeof CompressionAlgorithms;
type SharedCompressionFilterConfig = {
serverSupportedEncodingHeader?: string;
};
abstract class CompressionHandler {
protected abstract compressMessage(message: Buffer): Promise<Buffer>;
protected abstract decompressMessage(data: Buffer): Promise<Buffer>;
/**
* @param message Raw uncompressed message bytes
* @param compress Indicates whether the message should be compressed
* @return Framed message, compressed if applicable
*/
async writeMessage(message: Buffer, compress: boolean): Promise<Buffer> {
let messageBuffer = message;
if (compress) {
messageBuffer = await this.compressMessage(messageBuffer);
}
const output = Buffer.allocUnsafe(messageBuffer.length + 5);
output.writeUInt8(compress ? 1 : 0, 0);
output.writeUInt32BE(messageBuffer.length, 1);
messageBuffer.copy(output, 5);
return output;
}
/**
* @param data Framed message, possibly compressed
* @return Uncompressed message
*/
async readMessage(data: Buffer): Promise<Buffer> {
const compressed = data.readUInt8(0) === 1;
let messageBuffer: Buffer<ArrayBufferLike> = data.slice(5);
if (compressed) {
messageBuffer = await this.decompressMessage(messageBuffer);
}
return messageBuffer;
}
}
class IdentityHandler extends CompressionHandler {
async compressMessage(message: Buffer) {
return message;
}
async writeMessage(message: Buffer, compress: boolean): Promise<Buffer> {
const output = Buffer.allocUnsafe(message.length + 5);
/* With "identity" compression, messages should always be marked as
* uncompressed */
output.writeUInt8(0, 0);
output.writeUInt32BE(message.length, 1);
message.copy(output, 5);
return output;
}
decompressMessage(message: Buffer): Promise<Buffer> {
return Promise.reject<Buffer>(
new Error(
'Received compressed message but "grpc-encoding" header was identity'
)
);
}
}
class DeflateHandler extends CompressionHandler {
constructor(private maxRecvMessageLength: number) {
super();
}
compressMessage(message: Buffer) {
return new Promise<Buffer>((resolve, reject) => {
zlib.deflate(message, (err, output) => {
if (err) {
reject(err);
} else {
resolve(output);
}
});
});
}
decompressMessage(message: Buffer) {
return new Promise<Buffer>((resolve, reject) => {
let totalLength = 0;
const messageParts: Buffer[] = [];
const decompresser = zlib.createInflate();
decompresser.on('data', (chunk: Buffer) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});
}
}
class GzipHandler extends CompressionHandler {
constructor(private maxRecvMessageLength: number) {
super();
}
compressMessage(message: Buffer) {
return new Promise<Buffer>((resolve, reject) => {
zlib.gzip(message, (err, output) => {
if (err) {
reject(err);
} else {
resolve(output);
}
});
});
}
decompressMessage(message: Buffer) {
return new Promise<Buffer>((resolve, reject) => {
let totalLength = 0;
const messageParts: Buffer[] = [];
const decompresser = zlib.createGunzip();
decompresser.on('data', (chunk: Buffer) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});
}
}
class UnknownHandler extends CompressionHandler {
constructor(private readonly compressionName: string) {
super();
}
compressMessage(message: Buffer): Promise<Buffer> {
return Promise.reject<Buffer>(
new Error(
`Received message compressed with unsupported compression method ${this.compressionName}`
)
);
}
decompressMessage(message: Buffer): Promise<Buffer> {
// This should be unreachable
return Promise.reject<Buffer>(
new Error(`Compression method not supported: ${this.compressionName}`)
);
}
}
function getCompressionHandler(compressionName: string, maxReceiveMessageSize: number): CompressionHandler {
switch (compressionName) {
case 'identity':
return new IdentityHandler();
case 'deflate':
return new DeflateHandler(maxReceiveMessageSize);
case 'gzip':
return new GzipHandler(maxReceiveMessageSize);
default:
return new UnknownHandler(compressionName);
}
}
export class CompressionFilter extends BaseFilter implements Filter {
private sendCompression: CompressionHandler = new IdentityHandler();
private receiveCompression: CompressionHandler = new IdentityHandler();
private currentCompressionAlgorithm: CompressionAlgorithm = 'identity';
private maxReceiveMessageLength: number;
private maxSendMessageLength: number;
constructor(
channelOptions: ChannelOptions,
private sharedFilterConfig: SharedCompressionFilterConfig
) {
super();
const compressionAlgorithmKey =
channelOptions['grpc.default_compression_algorithm'];
this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH;
this.maxSendMessageLength = channelOptions['grpc.max_send_message_length'] ?? DEFAULT_MAX_SEND_MESSAGE_LENGTH;
if (compressionAlgorithmKey !== undefined) {
if (isCompressionAlgorithmKey(compressionAlgorithmKey)) {
const clientSelectedEncoding = CompressionAlgorithms[
compressionAlgorithmKey
] as CompressionAlgorithm;
const serverSupportedEncodings =
sharedFilterConfig.serverSupportedEncodingHeader?.split(',');
/**
* There are two possible situations here:
* 1) We don't have any info yet from the server about what compression it supports
* In that case we should just use what the client tells us to use
* 2) We've previously received a response from the server including a grpc-accept-encoding header
* In that case we only want to use the encoding chosen by the client if the server supports it
*/
if (
!serverSupportedEncodings ||
serverSupportedEncodings.includes(clientSelectedEncoding)
) {
this.currentCompressionAlgorithm = clientSelectedEncoding;
this.sendCompression = getCompressionHandler(
this.currentCompressionAlgorithm,
-1
);
}
} else {
logging.log(
LogVerbosity.ERROR,
`Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`
);
}
}
}
async sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
const headers: Metadata = await metadata;
headers.set('grpc-accept-encoding', 'identity,deflate,gzip');
headers.set('accept-encoding', 'identity');
// No need to send the header if it's "identity" - behavior is identical; save the bandwidth
if (this.currentCompressionAlgorithm === 'identity') {
headers.remove('grpc-encoding');
} else {
headers.set('grpc-encoding', this.currentCompressionAlgorithm);
}
return headers;
}
receiveMetadata(metadata: Metadata): Metadata {
const receiveEncoding: MetadataValue[] = metadata.get('grpc-encoding');
if (receiveEncoding.length > 0) {
const encoding: MetadataValue = receiveEncoding[0];
if (typeof encoding === 'string') {
this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength);
}
}
metadata.remove('grpc-encoding');
/* Check to see if the compression we're using to send messages is supported by the server
* If not, reset the sendCompression filter and have it use the default IdentityHandler */
const serverSupportedEncodingsHeader = metadata.get(
'grpc-accept-encoding'
)[0] as string | undefined;
if (serverSupportedEncodingsHeader) {
this.sharedFilterConfig.serverSupportedEncodingHeader =
serverSupportedEncodingsHeader;
const serverSupportedEncodings =
serverSupportedEncodingsHeader.split(',');
if (
!serverSupportedEncodings.includes(this.currentCompressionAlgorithm)
) {
this.sendCompression = new IdentityHandler();
this.currentCompressionAlgorithm = 'identity';
}
}
metadata.remove('grpc-accept-encoding');
return metadata;
}
async sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
/* This filter is special. The input message is the bare message bytes,
* and the output is a framed and possibly compressed message. For this
* reason, this filter should be at the bottom of the filter stack */
const resolvedMessage: WriteObject = await message;
if (this.maxSendMessageLength !== -1 && resolvedMessage.message.length > this.maxSendMessageLength) {
throw {
code: Status.RESOURCE_EXHAUSTED,
details: `Attempted to send message with a size larger than ${this.maxSendMessageLength}`
};
}
let compress: boolean;
if (this.sendCompression instanceof IdentityHandler) {
compress = false;
} else {
compress = ((resolvedMessage.flags ?? 0) & WriteFlags.NoCompress) === 0;
}
return {
message: await this.sendCompression.writeMessage(
resolvedMessage.message,
compress
),
flags: resolvedMessage.flags,
};
}
async receiveMessage(message: Promise<Buffer>) {
/* This filter is also special. The input message is framed and possibly
* compressed, and the output message is deframed and uncompressed. So
* this is another reason that this filter should be at the bottom of the
* filter stack. */
return this.receiveCompression.readMessage(await message);
}
}
export class CompressionFilterFactory
implements FilterFactory<CompressionFilter>
{
private sharedFilterConfig: SharedCompressionFilterConfig = {};
constructor(channel: Channel, private readonly options: ChannelOptions) {}
createFilter(): CompressionFilter {
return new CompressionFilter(this.options, this.sharedFilterConfig);
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export enum ConnectivityState {
IDLE,
CONNECTING,
READY,
TRANSIENT_FAILURE,
SHUTDOWN,
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export enum Status {
OK = 0,
CANCELLED,
UNKNOWN,
INVALID_ARGUMENT,
DEADLINE_EXCEEDED,
NOT_FOUND,
ALREADY_EXISTS,
PERMISSION_DENIED,
RESOURCE_EXHAUSTED,
FAILED_PRECONDITION,
ABORTED,
OUT_OF_RANGE,
UNIMPLEMENTED,
INTERNAL,
UNAVAILABLE,
DATA_LOSS,
UNAUTHENTICATED,
}
export enum LogVerbosity {
DEBUG = 0,
INFO,
ERROR,
NONE,
}
/**
* NOTE: This enum is not currently used in any implemented API in this
* library. It is included only for type parity with the other implementation.
*/
export enum Propagate {
DEADLINE = 1,
CENSUS_STATS_CONTEXT = 2,
CENSUS_TRACING_CONTEXT = 4,
CANCELLATION = 8,
// https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43
DEFAULTS = 0xffff |
Propagate.DEADLINE |
Propagate.CENSUS_STATS_CONTEXT |
Propagate.CENSUS_TRACING_CONTEXT |
Propagate.CANCELLATION,
}
// -1 means unlimited
export const DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
// 4 MB default
export const DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024;

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { Status } from './constants';
const INAPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [
Status.OK,
Status.INVALID_ARGUMENT,
Status.NOT_FOUND,
Status.ALREADY_EXISTS,
Status.FAILED_PRECONDITION,
Status.ABORTED,
Status.OUT_OF_RANGE,
Status.DATA_LOSS,
];
export function restrictControlPlaneStatusCode(
code: Status,
details: string
): { code: Status; details: string } {
if (INAPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) {
return {
code: Status.INTERNAL,
details: `Invalid status from control plane: ${code} ${Status[code]} ${details}`,
};
} else {
return { code, details };
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export type Deadline = Date | number;
export function minDeadline(...deadlineList: Deadline[]): Deadline {
let minValue = Infinity;
for (const deadline of deadlineList) {
const deadlineMsecs =
deadline instanceof Date ? deadline.getTime() : deadline;
if (deadlineMsecs < minValue) {
minValue = deadlineMsecs;
}
}
return minValue;
}
const units: Array<[string, number]> = [
['m', 1],
['S', 1000],
['M', 60 * 1000],
['H', 60 * 60 * 1000],
];
export function getDeadlineTimeoutString(deadline: Deadline) {
const now = new Date().getTime();
if (deadline instanceof Date) {
deadline = deadline.getTime();
}
const timeoutMs = Math.max(deadline - now, 0);
for (const [unit, factor] of units) {
const amount = timeoutMs / factor;
if (amount < 1e8) {
return String(Math.ceil(amount)) + unit;
}
}
throw new Error('Deadline is too far in the future');
}
/**
* See https://nodejs.org/api/timers.html#settimeoutcallback-delay-args
* In particular, "When delay is larger than 2147483647 or less than 1, the
* delay will be set to 1. Non-integer delays are truncated to an integer."
* This number of milliseconds is almost 25 days.
*/
const MAX_TIMEOUT_TIME = 2147483647;
/**
* Get the timeout value that should be passed to setTimeout now for the timer
* to end at the deadline. For any deadline before now, the timer should end
* immediately, represented by a value of 0. For any deadline more than
* MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will
* end at that time, so it is treated as infinitely far in the future.
* @param deadline
* @returns
*/
export function getRelativeTimeout(deadline: Deadline) {
const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline;
const now = new Date().getTime();
const timeout = deadlineMs - now;
if (timeout < 0) {
return 0;
} else if (timeout > MAX_TIMEOUT_TIME) {
return Infinity;
} else {
return timeout;
}
}
export function deadlineToString(deadline: Deadline): string {
if (deadline instanceof Date) {
return deadline.toISOString();
} else {
const dateDeadline = new Date(deadline);
if (Number.isNaN(dateDeadline.getTime())) {
return '' + deadline;
} else {
return dateDeadline.toISOString();
}
}
}
/**
* Calculate the difference between two dates as a number of seconds and format
* it as a string.
* @param startDate
* @param endDate
* @returns
*/
export function formatDateDifference(startDate: Date, endDate: Date): string {
return ((endDate.getTime() - startDate.getTime()) / 1000).toFixed(3) + 's';
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export interface Duration {
seconds: number;
nanos: number;
}
export interface DurationMessage {
seconds: string;
nanos: number;
}
export function durationMessageToDuration(message: DurationMessage): Duration {
return {
seconds: Number.parseInt(message.seconds),
nanos: message.nanos
};
}
export function msToDuration(millis: number): Duration {
return {
seconds: (millis / 1000) | 0,
nanos: ((millis % 1000) * 1_000_000) | 0,
};
}
export function durationToMs(duration: Duration): number {
return (duration.seconds * 1000 + duration.nanos / 1_000_000) | 0;
}
export function isDuration(value: any): value is Duration {
return typeof value.seconds === 'number' && typeof value.nanos === 'number';
}
export function isDurationMessage(value: any): value is DurationMessage {
return typeof value.seconds === 'string' && typeof value.nanos === 'number';
}
const durationRegex = /^(\d+)(?:\.(\d+))?s$/;
export function parseDuration(value: string): Duration | null {
const match = value.match(durationRegex);
if (!match) {
return null;
}
return {
seconds: Number.parseInt(match[1], 10),
nanos: match[2] ? Number.parseInt(match[2].padEnd(9, '0'), 10) : 0
};
}
export function durationToString(duration: Duration): string {
if (duration.nanos === 0) {
return `${duration.seconds}s`;
}
let scaleFactor: number;
if (duration.nanos % 1_000_000 === 0) {
scaleFactor = 1_000_000;
} else if (duration.nanos % 1_000 === 0) {
scaleFactor = 1_000;
} else {
scaleFactor = 1;
}
return `${duration.seconds}.${duration.nanos/scaleFactor}s`;
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export const GRPC_NODE_USE_ALTERNATIVE_RESOLVER =
(process.env.GRPC_NODE_USE_ALTERNATIVE_RESOLVER ?? 'false') === 'true';

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export function getErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message;
} else {
return String(error);
}
}
export function getErrorCode(error: unknown): number | null {
if (
typeof error === 'object' &&
error !== null &&
'code' in error &&
typeof (error as Record<string, unknown>).code === 'number'
) {
return (error as Record<string, number>).code;
} else {
return null;
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export interface EmitterAugmentation1<Name extends string | symbol, Arg> {
addListener(event: Name, listener: (arg1: Arg) => void): this;
emit(event: Name, arg1: Arg): boolean;
on(event: Name, listener: (arg1: Arg) => void): this;
once(event: Name, listener: (arg1: Arg) => void): this;
prependListener(event: Name, listener: (arg1: Arg) => void): this;
prependOnceListener(event: Name, listener: (arg1: Arg) => void): this;
removeListener(event: Name, listener: (arg1: Arg) => void): this;
}

View File

@@ -0,0 +1,73 @@
export { trace, log } from './logging';
export {
Resolver,
ResolverListener,
registerResolver,
ConfigSelector,
createResolver,
CHANNEL_ARGS_CONFIG_SELECTOR_KEY,
} from './resolver';
export { GrpcUri, uriToString, splitHostPort, HostPort } from './uri-parser';
export { Duration, durationToMs, parseDuration } from './duration';
export { BackoffTimeout } from './backoff-timeout';
export {
LoadBalancer,
TypedLoadBalancingConfig,
ChannelControlHelper,
createChildChannelControlHelper,
registerLoadBalancerType,
selectLbConfigFromList,
parseLoadBalancingConfig,
isLoadBalancerNameRegistered,
} from './load-balancer';
export { LeafLoadBalancer } from './load-balancer-pick-first';
export {
SubchannelAddress,
subchannelAddressToString,
Endpoint,
endpointToString,
endpointHasAddress,
EndpointMap,
} from './subchannel-address';
export { ChildLoadBalancerHandler } from './load-balancer-child-handler';
export {
Picker,
UnavailablePicker,
QueuePicker,
PickResult,
PickArgs,
PickResultType,
} from './picker';
export {
Call as CallStream,
StatusOr,
statusOrFromValue,
statusOrFromError
} from './call-interface';
export { Filter, BaseFilter, FilterFactory } from './filter';
export { FilterStackFactory } from './filter-stack';
export { registerAdminService } from './admin';
export {
SubchannelInterface,
BaseSubchannelWrapper,
ConnectivityStateListener,
HealthListener,
} from './subchannel-interface';
export {
OutlierDetectionRawConfig,
SuccessRateEjectionConfig,
FailurePercentageEjectionConfig,
} from './load-balancer-outlier-detection';
export { createServerCredentialsWithInterceptors, createCertificateProviderServerCredentials } from './server-credentials';
export {
CaCertificateUpdate,
CaCertificateUpdateListener,
IdentityCertificateUpdate,
IdentityCertificateUpdateListener,
CertificateProvider,
FileWatcherCertificateProvider,
FileWatcherCertificateProviderConfig
} from './certificate-provider';
export { createCertificateProviderChannelCredentials, SecureConnector, SecureConnectResult } from './channel-credentials';
export { SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX } from './internal-channel';

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { StatusObject, WriteObject } from './call-interface';
import { Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
export class FilterStack implements Filter {
constructor(private readonly filters: Filter[]) {}
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
let result: Promise<Metadata> = metadata;
for (let i = 0; i < this.filters.length; i++) {
result = this.filters[i].sendMetadata(result);
}
return result;
}
receiveMetadata(metadata: Metadata) {
let result: Metadata = metadata;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveMetadata(result);
}
return result;
}
sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
let result: Promise<WriteObject> = message;
for (let i = 0; i < this.filters.length; i++) {
result = this.filters[i].sendMessage(result);
}
return result;
}
receiveMessage(message: Promise<Buffer>): Promise<Buffer> {
let result: Promise<Buffer> = message;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveMessage(result);
}
return result;
}
receiveTrailers(status: StatusObject): StatusObject {
let result: StatusObject = status;
for (let i = this.filters.length - 1; i >= 0; i--) {
result = this.filters[i].receiveTrailers(result);
}
return result;
}
push(filters: Filter[]) {
this.filters.unshift(...filters);
}
getFilters(): Filter[] {
return this.filters;
}
}
export class FilterStackFactory implements FilterFactory<FilterStack> {
constructor(private readonly factories: Array<FilterFactory<Filter>>) {}
push(filterFactories: FilterFactory<Filter>[]) {
this.factories.unshift(...filterFactories);
}
clone(): FilterStackFactory {
return new FilterStackFactory([...this.factories]);
}
createFilter(): FilterStack {
return new FilterStack(
this.factories.map(factory => factory.createFilter())
);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { StatusObject, WriteObject } from './call-interface';
import { Metadata } from './metadata';
/**
* Filter classes represent related per-call logic and state that is primarily
* used to modify incoming and outgoing data. All async filters can be
* rejected. The rejection error must be a StatusObject, and a rejection will
* cause the call to end with that status.
*/
export interface Filter {
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
receiveMetadata(metadata: Metadata): Metadata;
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
receiveTrailers(status: StatusObject): StatusObject;
}
export abstract class BaseFilter implements Filter {
async sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
return metadata;
}
receiveMetadata(metadata: Metadata): Metadata {
return metadata;
}
async sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
return message;
}
async receiveMessage(message: Promise<Buffer>): Promise<Buffer> {
return message;
}
receiveTrailers(status: StatusObject): StatusObject {
return status;
}
}
export interface FilterFactory<T extends Filter> {
createFilter(): T;
}

View File

@@ -0,0 +1,119 @@
import type * as grpc from '../index';
import type { MessageTypeDefinition } from '@grpc/proto-loader';
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from './google/protobuf/Any';
import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from './google/protobuf/BoolValue';
import type { BytesValue as _google_protobuf_BytesValue, BytesValue__Output as _google_protobuf_BytesValue__Output } from './google/protobuf/BytesValue';
import type { DoubleValue as _google_protobuf_DoubleValue, DoubleValue__Output as _google_protobuf_DoubleValue__Output } from './google/protobuf/DoubleValue';
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from './google/protobuf/Duration';
import type { FloatValue as _google_protobuf_FloatValue, FloatValue__Output as _google_protobuf_FloatValue__Output } from './google/protobuf/FloatValue';
import type { Int32Value as _google_protobuf_Int32Value, Int32Value__Output as _google_protobuf_Int32Value__Output } from './google/protobuf/Int32Value';
import type { Int64Value as _google_protobuf_Int64Value, Int64Value__Output as _google_protobuf_Int64Value__Output } from './google/protobuf/Int64Value';
import type { StringValue as _google_protobuf_StringValue, StringValue__Output as _google_protobuf_StringValue__Output } from './google/protobuf/StringValue';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from './google/protobuf/Timestamp';
import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from './google/protobuf/UInt32Value';
import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from './google/protobuf/UInt64Value';
import type { Address as _grpc_channelz_v1_Address, Address__Output as _grpc_channelz_v1_Address__Output } from './grpc/channelz/v1/Address';
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from './grpc/channelz/v1/Channel';
import type { ChannelConnectivityState as _grpc_channelz_v1_ChannelConnectivityState, ChannelConnectivityState__Output as _grpc_channelz_v1_ChannelConnectivityState__Output } from './grpc/channelz/v1/ChannelConnectivityState';
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from './grpc/channelz/v1/ChannelData';
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from './grpc/channelz/v1/ChannelRef';
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from './grpc/channelz/v1/ChannelTrace';
import type { ChannelTraceEvent as _grpc_channelz_v1_ChannelTraceEvent, ChannelTraceEvent__Output as _grpc_channelz_v1_ChannelTraceEvent__Output } from './grpc/channelz/v1/ChannelTraceEvent';
import type { ChannelzClient as _grpc_channelz_v1_ChannelzClient, ChannelzDefinition as _grpc_channelz_v1_ChannelzDefinition } from './grpc/channelz/v1/Channelz';
import type { GetChannelRequest as _grpc_channelz_v1_GetChannelRequest, GetChannelRequest__Output as _grpc_channelz_v1_GetChannelRequest__Output } from './grpc/channelz/v1/GetChannelRequest';
import type { GetChannelResponse as _grpc_channelz_v1_GetChannelResponse, GetChannelResponse__Output as _grpc_channelz_v1_GetChannelResponse__Output } from './grpc/channelz/v1/GetChannelResponse';
import type { GetServerRequest as _grpc_channelz_v1_GetServerRequest, GetServerRequest__Output as _grpc_channelz_v1_GetServerRequest__Output } from './grpc/channelz/v1/GetServerRequest';
import type { GetServerResponse as _grpc_channelz_v1_GetServerResponse, GetServerResponse__Output as _grpc_channelz_v1_GetServerResponse__Output } from './grpc/channelz/v1/GetServerResponse';
import type { GetServerSocketsRequest as _grpc_channelz_v1_GetServerSocketsRequest, GetServerSocketsRequest__Output as _grpc_channelz_v1_GetServerSocketsRequest__Output } from './grpc/channelz/v1/GetServerSocketsRequest';
import type { GetServerSocketsResponse as _grpc_channelz_v1_GetServerSocketsResponse, GetServerSocketsResponse__Output as _grpc_channelz_v1_GetServerSocketsResponse__Output } from './grpc/channelz/v1/GetServerSocketsResponse';
import type { GetServersRequest as _grpc_channelz_v1_GetServersRequest, GetServersRequest__Output as _grpc_channelz_v1_GetServersRequest__Output } from './grpc/channelz/v1/GetServersRequest';
import type { GetServersResponse as _grpc_channelz_v1_GetServersResponse, GetServersResponse__Output as _grpc_channelz_v1_GetServersResponse__Output } from './grpc/channelz/v1/GetServersResponse';
import type { GetSocketRequest as _grpc_channelz_v1_GetSocketRequest, GetSocketRequest__Output as _grpc_channelz_v1_GetSocketRequest__Output } from './grpc/channelz/v1/GetSocketRequest';
import type { GetSocketResponse as _grpc_channelz_v1_GetSocketResponse, GetSocketResponse__Output as _grpc_channelz_v1_GetSocketResponse__Output } from './grpc/channelz/v1/GetSocketResponse';
import type { GetSubchannelRequest as _grpc_channelz_v1_GetSubchannelRequest, GetSubchannelRequest__Output as _grpc_channelz_v1_GetSubchannelRequest__Output } from './grpc/channelz/v1/GetSubchannelRequest';
import type { GetSubchannelResponse as _grpc_channelz_v1_GetSubchannelResponse, GetSubchannelResponse__Output as _grpc_channelz_v1_GetSubchannelResponse__Output } from './grpc/channelz/v1/GetSubchannelResponse';
import type { GetTopChannelsRequest as _grpc_channelz_v1_GetTopChannelsRequest, GetTopChannelsRequest__Output as _grpc_channelz_v1_GetTopChannelsRequest__Output } from './grpc/channelz/v1/GetTopChannelsRequest';
import type { GetTopChannelsResponse as _grpc_channelz_v1_GetTopChannelsResponse, GetTopChannelsResponse__Output as _grpc_channelz_v1_GetTopChannelsResponse__Output } from './grpc/channelz/v1/GetTopChannelsResponse';
import type { Security as _grpc_channelz_v1_Security, Security__Output as _grpc_channelz_v1_Security__Output } from './grpc/channelz/v1/Security';
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from './grpc/channelz/v1/Server';
import type { ServerData as _grpc_channelz_v1_ServerData, ServerData__Output as _grpc_channelz_v1_ServerData__Output } from './grpc/channelz/v1/ServerData';
import type { ServerRef as _grpc_channelz_v1_ServerRef, ServerRef__Output as _grpc_channelz_v1_ServerRef__Output } from './grpc/channelz/v1/ServerRef';
import type { Socket as _grpc_channelz_v1_Socket, Socket__Output as _grpc_channelz_v1_Socket__Output } from './grpc/channelz/v1/Socket';
import type { SocketData as _grpc_channelz_v1_SocketData, SocketData__Output as _grpc_channelz_v1_SocketData__Output } from './grpc/channelz/v1/SocketData';
import type { SocketOption as _grpc_channelz_v1_SocketOption, SocketOption__Output as _grpc_channelz_v1_SocketOption__Output } from './grpc/channelz/v1/SocketOption';
import type { SocketOptionLinger as _grpc_channelz_v1_SocketOptionLinger, SocketOptionLinger__Output as _grpc_channelz_v1_SocketOptionLinger__Output } from './grpc/channelz/v1/SocketOptionLinger';
import type { SocketOptionTcpInfo as _grpc_channelz_v1_SocketOptionTcpInfo, SocketOptionTcpInfo__Output as _grpc_channelz_v1_SocketOptionTcpInfo__Output } from './grpc/channelz/v1/SocketOptionTcpInfo';
import type { SocketOptionTimeout as _grpc_channelz_v1_SocketOptionTimeout, SocketOptionTimeout__Output as _grpc_channelz_v1_SocketOptionTimeout__Output } from './grpc/channelz/v1/SocketOptionTimeout';
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from './grpc/channelz/v1/SocketRef';
import type { Subchannel as _grpc_channelz_v1_Subchannel, Subchannel__Output as _grpc_channelz_v1_Subchannel__Output } from './grpc/channelz/v1/Subchannel';
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from './grpc/channelz/v1/SubchannelRef';
type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
new(...args: ConstructorParameters<Constructor>): Subtype;
};
export interface ProtoGrpcType {
google: {
protobuf: {
Any: MessageTypeDefinition<_google_protobuf_Any, _google_protobuf_Any__Output>
BoolValue: MessageTypeDefinition<_google_protobuf_BoolValue, _google_protobuf_BoolValue__Output>
BytesValue: MessageTypeDefinition<_google_protobuf_BytesValue, _google_protobuf_BytesValue__Output>
DoubleValue: MessageTypeDefinition<_google_protobuf_DoubleValue, _google_protobuf_DoubleValue__Output>
Duration: MessageTypeDefinition<_google_protobuf_Duration, _google_protobuf_Duration__Output>
FloatValue: MessageTypeDefinition<_google_protobuf_FloatValue, _google_protobuf_FloatValue__Output>
Int32Value: MessageTypeDefinition<_google_protobuf_Int32Value, _google_protobuf_Int32Value__Output>
Int64Value: MessageTypeDefinition<_google_protobuf_Int64Value, _google_protobuf_Int64Value__Output>
StringValue: MessageTypeDefinition<_google_protobuf_StringValue, _google_protobuf_StringValue__Output>
Timestamp: MessageTypeDefinition<_google_protobuf_Timestamp, _google_protobuf_Timestamp__Output>
UInt32Value: MessageTypeDefinition<_google_protobuf_UInt32Value, _google_protobuf_UInt32Value__Output>
UInt64Value: MessageTypeDefinition<_google_protobuf_UInt64Value, _google_protobuf_UInt64Value__Output>
}
}
grpc: {
channelz: {
v1: {
Address: MessageTypeDefinition<_grpc_channelz_v1_Address, _grpc_channelz_v1_Address__Output>
Channel: MessageTypeDefinition<_grpc_channelz_v1_Channel, _grpc_channelz_v1_Channel__Output>
ChannelConnectivityState: MessageTypeDefinition<_grpc_channelz_v1_ChannelConnectivityState, _grpc_channelz_v1_ChannelConnectivityState__Output>
ChannelData: MessageTypeDefinition<_grpc_channelz_v1_ChannelData, _grpc_channelz_v1_ChannelData__Output>
ChannelRef: MessageTypeDefinition<_grpc_channelz_v1_ChannelRef, _grpc_channelz_v1_ChannelRef__Output>
ChannelTrace: MessageTypeDefinition<_grpc_channelz_v1_ChannelTrace, _grpc_channelz_v1_ChannelTrace__Output>
ChannelTraceEvent: MessageTypeDefinition<_grpc_channelz_v1_ChannelTraceEvent, _grpc_channelz_v1_ChannelTraceEvent__Output>
/**
* Channelz is a service exposed by gRPC servers that provides detailed debug
* information.
*/
Channelz: SubtypeConstructor<typeof grpc.Client, _grpc_channelz_v1_ChannelzClient> & { service: _grpc_channelz_v1_ChannelzDefinition }
GetChannelRequest: MessageTypeDefinition<_grpc_channelz_v1_GetChannelRequest, _grpc_channelz_v1_GetChannelRequest__Output>
GetChannelResponse: MessageTypeDefinition<_grpc_channelz_v1_GetChannelResponse, _grpc_channelz_v1_GetChannelResponse__Output>
GetServerRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServerRequest, _grpc_channelz_v1_GetServerRequest__Output>
GetServerResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServerResponse, _grpc_channelz_v1_GetServerResponse__Output>
GetServerSocketsRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServerSocketsRequest, _grpc_channelz_v1_GetServerSocketsRequest__Output>
GetServerSocketsResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServerSocketsResponse, _grpc_channelz_v1_GetServerSocketsResponse__Output>
GetServersRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServersRequest, _grpc_channelz_v1_GetServersRequest__Output>
GetServersResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServersResponse, _grpc_channelz_v1_GetServersResponse__Output>
GetSocketRequest: MessageTypeDefinition<_grpc_channelz_v1_GetSocketRequest, _grpc_channelz_v1_GetSocketRequest__Output>
GetSocketResponse: MessageTypeDefinition<_grpc_channelz_v1_GetSocketResponse, _grpc_channelz_v1_GetSocketResponse__Output>
GetSubchannelRequest: MessageTypeDefinition<_grpc_channelz_v1_GetSubchannelRequest, _grpc_channelz_v1_GetSubchannelRequest__Output>
GetSubchannelResponse: MessageTypeDefinition<_grpc_channelz_v1_GetSubchannelResponse, _grpc_channelz_v1_GetSubchannelResponse__Output>
GetTopChannelsRequest: MessageTypeDefinition<_grpc_channelz_v1_GetTopChannelsRequest, _grpc_channelz_v1_GetTopChannelsRequest__Output>
GetTopChannelsResponse: MessageTypeDefinition<_grpc_channelz_v1_GetTopChannelsResponse, _grpc_channelz_v1_GetTopChannelsResponse__Output>
Security: MessageTypeDefinition<_grpc_channelz_v1_Security, _grpc_channelz_v1_Security__Output>
Server: MessageTypeDefinition<_grpc_channelz_v1_Server, _grpc_channelz_v1_Server__Output>
ServerData: MessageTypeDefinition<_grpc_channelz_v1_ServerData, _grpc_channelz_v1_ServerData__Output>
ServerRef: MessageTypeDefinition<_grpc_channelz_v1_ServerRef, _grpc_channelz_v1_ServerRef__Output>
Socket: MessageTypeDefinition<_grpc_channelz_v1_Socket, _grpc_channelz_v1_Socket__Output>
SocketData: MessageTypeDefinition<_grpc_channelz_v1_SocketData, _grpc_channelz_v1_SocketData__Output>
SocketOption: MessageTypeDefinition<_grpc_channelz_v1_SocketOption, _grpc_channelz_v1_SocketOption__Output>
SocketOptionLinger: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionLinger, _grpc_channelz_v1_SocketOptionLinger__Output>
SocketOptionTcpInfo: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionTcpInfo, _grpc_channelz_v1_SocketOptionTcpInfo__Output>
SocketOptionTimeout: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionTimeout, _grpc_channelz_v1_SocketOptionTimeout__Output>
SocketRef: MessageTypeDefinition<_grpc_channelz_v1_SocketRef, _grpc_channelz_v1_SocketRef__Output>
Subchannel: MessageTypeDefinition<_grpc_channelz_v1_Subchannel, _grpc_channelz_v1_Subchannel__Output>
SubchannelRef: MessageTypeDefinition<_grpc_channelz_v1_SubchannelRef, _grpc_channelz_v1_SubchannelRef__Output>
}
}
}
}

View File

@@ -0,0 +1,13 @@
// Original file: null
import type { AnyExtension } from '@grpc/proto-loader';
export type Any = AnyExtension | {
type_url: string;
value: Buffer | Uint8Array | string;
}
export interface Any__Output {
'type_url': (string);
'value': (Buffer);
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface BoolValue {
'value'?: (boolean);
}
export interface BoolValue__Output {
'value': (boolean);
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface BytesValue {
'value'?: (Buffer | Uint8Array | string);
}
export interface BytesValue__Output {
'value': (Buffer);
}

View File

@@ -0,0 +1,59 @@
// Original file: null
import type { FieldDescriptorProto as _google_protobuf_FieldDescriptorProto, FieldDescriptorProto__Output as _google_protobuf_FieldDescriptorProto__Output } from '../../google/protobuf/FieldDescriptorProto';
import type { DescriptorProto as _google_protobuf_DescriptorProto, DescriptorProto__Output as _google_protobuf_DescriptorProto__Output } from '../../google/protobuf/DescriptorProto';
import type { EnumDescriptorProto as _google_protobuf_EnumDescriptorProto, EnumDescriptorProto__Output as _google_protobuf_EnumDescriptorProto__Output } from '../../google/protobuf/EnumDescriptorProto';
import type { MessageOptions as _google_protobuf_MessageOptions, MessageOptions__Output as _google_protobuf_MessageOptions__Output } from '../../google/protobuf/MessageOptions';
import type { OneofDescriptorProto as _google_protobuf_OneofDescriptorProto, OneofDescriptorProto__Output as _google_protobuf_OneofDescriptorProto__Output } from '../../google/protobuf/OneofDescriptorProto';
import type { SymbolVisibility as _google_protobuf_SymbolVisibility, SymbolVisibility__Output as _google_protobuf_SymbolVisibility__Output } from '../../google/protobuf/SymbolVisibility';
import type { ExtensionRangeOptions as _google_protobuf_ExtensionRangeOptions, ExtensionRangeOptions__Output as _google_protobuf_ExtensionRangeOptions__Output } from '../../google/protobuf/ExtensionRangeOptions';
export interface _google_protobuf_DescriptorProto_ExtensionRange {
'start'?: (number);
'end'?: (number);
'options'?: (_google_protobuf_ExtensionRangeOptions | null);
}
export interface _google_protobuf_DescriptorProto_ExtensionRange__Output {
'start': (number);
'end': (number);
'options': (_google_protobuf_ExtensionRangeOptions__Output | null);
}
export interface _google_protobuf_DescriptorProto_ReservedRange {
'start'?: (number);
'end'?: (number);
}
export interface _google_protobuf_DescriptorProto_ReservedRange__Output {
'start': (number);
'end': (number);
}
export interface DescriptorProto {
'name'?: (string);
'field'?: (_google_protobuf_FieldDescriptorProto)[];
'nestedType'?: (_google_protobuf_DescriptorProto)[];
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[];
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
'options'?: (_google_protobuf_MessageOptions | null);
'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[];
'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[];
'reservedName'?: (string)[];
'visibility'?: (_google_protobuf_SymbolVisibility);
}
export interface DescriptorProto__Output {
'name': (string);
'field': (_google_protobuf_FieldDescriptorProto__Output)[];
'nestedType': (_google_protobuf_DescriptorProto__Output)[];
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[];
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
'options': (_google_protobuf_MessageOptions__Output | null);
'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[];
'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[];
'reservedName': (string)[];
'visibility': (_google_protobuf_SymbolVisibility__Output);
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface DoubleValue {
'value'?: (number | string);
}
export interface DoubleValue__Output {
'value': (number);
}

View File

@@ -0,0 +1,13 @@
// Original file: null
import type { Long } from '@grpc/proto-loader';
export interface Duration {
'seconds'?: (number | string | Long);
'nanos'?: (number);
}
export interface Duration__Output {
'seconds': (string);
'nanos': (number);
}

View File

@@ -0,0 +1,44 @@
// Original file: null
export const Edition = {
EDITION_UNKNOWN: 'EDITION_UNKNOWN',
EDITION_LEGACY: 'EDITION_LEGACY',
EDITION_PROTO2: 'EDITION_PROTO2',
EDITION_PROTO3: 'EDITION_PROTO3',
EDITION_2023: 'EDITION_2023',
EDITION_2024: 'EDITION_2024',
EDITION_1_TEST_ONLY: 'EDITION_1_TEST_ONLY',
EDITION_2_TEST_ONLY: 'EDITION_2_TEST_ONLY',
EDITION_99997_TEST_ONLY: 'EDITION_99997_TEST_ONLY',
EDITION_99998_TEST_ONLY: 'EDITION_99998_TEST_ONLY',
EDITION_99999_TEST_ONLY: 'EDITION_99999_TEST_ONLY',
EDITION_MAX: 'EDITION_MAX',
} as const;
export type Edition =
| 'EDITION_UNKNOWN'
| 0
| 'EDITION_LEGACY'
| 900
| 'EDITION_PROTO2'
| 998
| 'EDITION_PROTO3'
| 999
| 'EDITION_2023'
| 1000
| 'EDITION_2024'
| 1001
| 'EDITION_1_TEST_ONLY'
| 1
| 'EDITION_2_TEST_ONLY'
| 2
| 'EDITION_99997_TEST_ONLY'
| 99997
| 'EDITION_99998_TEST_ONLY'
| 99998
| 'EDITION_99999_TEST_ONLY'
| 99999
| 'EDITION_MAX'
| 2147483647
export type Edition__Output = typeof Edition[keyof typeof Edition]

View File

@@ -0,0 +1,33 @@
// Original file: null
import type { EnumValueDescriptorProto as _google_protobuf_EnumValueDescriptorProto, EnumValueDescriptorProto__Output as _google_protobuf_EnumValueDescriptorProto__Output } from '../../google/protobuf/EnumValueDescriptorProto';
import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output as _google_protobuf_EnumOptions__Output } from '../../google/protobuf/EnumOptions';
import type { SymbolVisibility as _google_protobuf_SymbolVisibility, SymbolVisibility__Output as _google_protobuf_SymbolVisibility__Output } from '../../google/protobuf/SymbolVisibility';
export interface _google_protobuf_EnumDescriptorProto_EnumReservedRange {
'start'?: (number);
'end'?: (number);
}
export interface _google_protobuf_EnumDescriptorProto_EnumReservedRange__Output {
'start': (number);
'end': (number);
}
export interface EnumDescriptorProto {
'name'?: (string);
'value'?: (_google_protobuf_EnumValueDescriptorProto)[];
'options'?: (_google_protobuf_EnumOptions | null);
'reservedRange'?: (_google_protobuf_EnumDescriptorProto_EnumReservedRange)[];
'reservedName'?: (string)[];
'visibility'?: (_google_protobuf_SymbolVisibility);
}
export interface EnumDescriptorProto__Output {
'name': (string);
'value': (_google_protobuf_EnumValueDescriptorProto__Output)[];
'options': (_google_protobuf_EnumOptions__Output | null);
'reservedRange': (_google_protobuf_EnumDescriptorProto_EnumReservedRange__Output)[];
'reservedName': (string)[];
'visibility': (_google_protobuf_SymbolVisibility__Output);
}

View File

@@ -0,0 +1,26 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface EnumOptions {
'allowAlias'?: (boolean);
'deprecated'?: (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface EnumOptions__Output {
'allowAlias': (boolean);
'deprecated': (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,15 @@
// Original file: null
import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOptions__Output as _google_protobuf_EnumValueOptions__Output } from '../../google/protobuf/EnumValueOptions';
export interface EnumValueDescriptorProto {
'name'?: (string);
'number'?: (number);
'options'?: (_google_protobuf_EnumValueOptions | null);
}
export interface EnumValueDescriptorProto__Output {
'name': (string);
'number': (number);
'options': (_google_protobuf_EnumValueOptions__Output | null);
}

View File

@@ -0,0 +1,21 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { _google_protobuf_FieldOptions_FeatureSupport, _google_protobuf_FieldOptions_FeatureSupport__Output } from '../../google/protobuf/FieldOptions';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface EnumValueOptions {
'deprecated'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'debugRedact'?: (boolean);
'featureSupport'?: (_google_protobuf_FieldOptions_FeatureSupport | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface EnumValueOptions__Output {
'deprecated': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'debugRedact': (boolean);
'featureSupport': (_google_protobuf_FieldOptions_FeatureSupport__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,49 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface _google_protobuf_ExtensionRangeOptions_Declaration {
'number'?: (number);
'fullName'?: (string);
'type'?: (string);
'reserved'?: (boolean);
'repeated'?: (boolean);
}
export interface _google_protobuf_ExtensionRangeOptions_Declaration__Output {
'number': (number);
'fullName': (string);
'type': (string);
'reserved': (boolean);
'repeated': (boolean);
}
// Original file: null
export const _google_protobuf_ExtensionRangeOptions_VerificationState = {
DECLARATION: 'DECLARATION',
UNVERIFIED: 'UNVERIFIED',
} as const;
export type _google_protobuf_ExtensionRangeOptions_VerificationState =
| 'DECLARATION'
| 0
| 'UNVERIFIED'
| 1
export type _google_protobuf_ExtensionRangeOptions_VerificationState__Output = typeof _google_protobuf_ExtensionRangeOptions_VerificationState[keyof typeof _google_protobuf_ExtensionRangeOptions_VerificationState]
export interface ExtensionRangeOptions {
'declaration'?: (_google_protobuf_ExtensionRangeOptions_Declaration)[];
'verification'?: (_google_protobuf_ExtensionRangeOptions_VerificationState);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface ExtensionRangeOptions__Output {
'declaration': (_google_protobuf_ExtensionRangeOptions_Declaration__Output)[];
'verification': (_google_protobuf_ExtensionRangeOptions_VerificationState__Output);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,183 @@
// Original file: null
// Original file: null
export const _google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility = {
DEFAULT_SYMBOL_VISIBILITY_UNKNOWN: 'DEFAULT_SYMBOL_VISIBILITY_UNKNOWN',
EXPORT_ALL: 'EXPORT_ALL',
EXPORT_TOP_LEVEL: 'EXPORT_TOP_LEVEL',
LOCAL_ALL: 'LOCAL_ALL',
STRICT: 'STRICT',
} as const;
export type _google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility =
| 'DEFAULT_SYMBOL_VISIBILITY_UNKNOWN'
| 0
| 'EXPORT_ALL'
| 1
| 'EXPORT_TOP_LEVEL'
| 2
| 'LOCAL_ALL'
| 3
| 'STRICT'
| 4
export type _google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility__Output = typeof _google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility[keyof typeof _google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility]
// Original file: null
export const _google_protobuf_FeatureSet_EnforceNamingStyle = {
ENFORCE_NAMING_STYLE_UNKNOWN: 'ENFORCE_NAMING_STYLE_UNKNOWN',
STYLE2024: 'STYLE2024',
STYLE_LEGACY: 'STYLE_LEGACY',
} as const;
export type _google_protobuf_FeatureSet_EnforceNamingStyle =
| 'ENFORCE_NAMING_STYLE_UNKNOWN'
| 0
| 'STYLE2024'
| 1
| 'STYLE_LEGACY'
| 2
export type _google_protobuf_FeatureSet_EnforceNamingStyle__Output = typeof _google_protobuf_FeatureSet_EnforceNamingStyle[keyof typeof _google_protobuf_FeatureSet_EnforceNamingStyle]
// Original file: null
export const _google_protobuf_FeatureSet_EnumType = {
ENUM_TYPE_UNKNOWN: 'ENUM_TYPE_UNKNOWN',
OPEN: 'OPEN',
CLOSED: 'CLOSED',
} as const;
export type _google_protobuf_FeatureSet_EnumType =
| 'ENUM_TYPE_UNKNOWN'
| 0
| 'OPEN'
| 1
| 'CLOSED'
| 2
export type _google_protobuf_FeatureSet_EnumType__Output = typeof _google_protobuf_FeatureSet_EnumType[keyof typeof _google_protobuf_FeatureSet_EnumType]
// Original file: null
export const _google_protobuf_FeatureSet_FieldPresence = {
FIELD_PRESENCE_UNKNOWN: 'FIELD_PRESENCE_UNKNOWN',
EXPLICIT: 'EXPLICIT',
IMPLICIT: 'IMPLICIT',
LEGACY_REQUIRED: 'LEGACY_REQUIRED',
} as const;
export type _google_protobuf_FeatureSet_FieldPresence =
| 'FIELD_PRESENCE_UNKNOWN'
| 0
| 'EXPLICIT'
| 1
| 'IMPLICIT'
| 2
| 'LEGACY_REQUIRED'
| 3
export type _google_protobuf_FeatureSet_FieldPresence__Output = typeof _google_protobuf_FeatureSet_FieldPresence[keyof typeof _google_protobuf_FeatureSet_FieldPresence]
// Original file: null
export const _google_protobuf_FeatureSet_JsonFormat = {
JSON_FORMAT_UNKNOWN: 'JSON_FORMAT_UNKNOWN',
ALLOW: 'ALLOW',
LEGACY_BEST_EFFORT: 'LEGACY_BEST_EFFORT',
} as const;
export type _google_protobuf_FeatureSet_JsonFormat =
| 'JSON_FORMAT_UNKNOWN'
| 0
| 'ALLOW'
| 1
| 'LEGACY_BEST_EFFORT'
| 2
export type _google_protobuf_FeatureSet_JsonFormat__Output = typeof _google_protobuf_FeatureSet_JsonFormat[keyof typeof _google_protobuf_FeatureSet_JsonFormat]
// Original file: null
export const _google_protobuf_FeatureSet_MessageEncoding = {
MESSAGE_ENCODING_UNKNOWN: 'MESSAGE_ENCODING_UNKNOWN',
LENGTH_PREFIXED: 'LENGTH_PREFIXED',
DELIMITED: 'DELIMITED',
} as const;
export type _google_protobuf_FeatureSet_MessageEncoding =
| 'MESSAGE_ENCODING_UNKNOWN'
| 0
| 'LENGTH_PREFIXED'
| 1
| 'DELIMITED'
| 2
export type _google_protobuf_FeatureSet_MessageEncoding__Output = typeof _google_protobuf_FeatureSet_MessageEncoding[keyof typeof _google_protobuf_FeatureSet_MessageEncoding]
// Original file: null
export const _google_protobuf_FeatureSet_RepeatedFieldEncoding = {
REPEATED_FIELD_ENCODING_UNKNOWN: 'REPEATED_FIELD_ENCODING_UNKNOWN',
PACKED: 'PACKED',
EXPANDED: 'EXPANDED',
} as const;
export type _google_protobuf_FeatureSet_RepeatedFieldEncoding =
| 'REPEATED_FIELD_ENCODING_UNKNOWN'
| 0
| 'PACKED'
| 1
| 'EXPANDED'
| 2
export type _google_protobuf_FeatureSet_RepeatedFieldEncoding__Output = typeof _google_protobuf_FeatureSet_RepeatedFieldEncoding[keyof typeof _google_protobuf_FeatureSet_RepeatedFieldEncoding]
// Original file: null
export const _google_protobuf_FeatureSet_Utf8Validation = {
UTF8_VALIDATION_UNKNOWN: 'UTF8_VALIDATION_UNKNOWN',
VERIFY: 'VERIFY',
NONE: 'NONE',
} as const;
export type _google_protobuf_FeatureSet_Utf8Validation =
| 'UTF8_VALIDATION_UNKNOWN'
| 0
| 'VERIFY'
| 2
| 'NONE'
| 3
export type _google_protobuf_FeatureSet_Utf8Validation__Output = typeof _google_protobuf_FeatureSet_Utf8Validation[keyof typeof _google_protobuf_FeatureSet_Utf8Validation]
export interface _google_protobuf_FeatureSet_VisibilityFeature {
}
export interface _google_protobuf_FeatureSet_VisibilityFeature__Output {
}
export interface FeatureSet {
'fieldPresence'?: (_google_protobuf_FeatureSet_FieldPresence);
'enumType'?: (_google_protobuf_FeatureSet_EnumType);
'repeatedFieldEncoding'?: (_google_protobuf_FeatureSet_RepeatedFieldEncoding);
'utf8Validation'?: (_google_protobuf_FeatureSet_Utf8Validation);
'messageEncoding'?: (_google_protobuf_FeatureSet_MessageEncoding);
'jsonFormat'?: (_google_protobuf_FeatureSet_JsonFormat);
'enforceNamingStyle'?: (_google_protobuf_FeatureSet_EnforceNamingStyle);
'defaultSymbolVisibility'?: (_google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility);
}
export interface FeatureSet__Output {
'fieldPresence': (_google_protobuf_FeatureSet_FieldPresence__Output);
'enumType': (_google_protobuf_FeatureSet_EnumType__Output);
'repeatedFieldEncoding': (_google_protobuf_FeatureSet_RepeatedFieldEncoding__Output);
'utf8Validation': (_google_protobuf_FeatureSet_Utf8Validation__Output);
'messageEncoding': (_google_protobuf_FeatureSet_MessageEncoding__Output);
'jsonFormat': (_google_protobuf_FeatureSet_JsonFormat__Output);
'enforceNamingStyle': (_google_protobuf_FeatureSet_EnforceNamingStyle__Output);
'defaultSymbolVisibility': (_google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility__Output);
}

View File

@@ -0,0 +1,28 @@
// Original file: null
import type { Edition as _google_protobuf_Edition, Edition__Output as _google_protobuf_Edition__Output } from '../../google/protobuf/Edition';
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
export interface _google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault {
'edition'?: (_google_protobuf_Edition);
'overridableFeatures'?: (_google_protobuf_FeatureSet | null);
'fixedFeatures'?: (_google_protobuf_FeatureSet | null);
}
export interface _google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__Output {
'edition': (_google_protobuf_Edition__Output);
'overridableFeatures': (_google_protobuf_FeatureSet__Output | null);
'fixedFeatures': (_google_protobuf_FeatureSet__Output | null);
}
export interface FeatureSetDefaults {
'defaults'?: (_google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault)[];
'minimumEdition'?: (_google_protobuf_Edition);
'maximumEdition'?: (_google_protobuf_Edition);
}
export interface FeatureSetDefaults__Output {
'defaults': (_google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__Output)[];
'minimumEdition': (_google_protobuf_Edition__Output);
'maximumEdition': (_google_protobuf_Edition__Output);
}

View File

@@ -0,0 +1,112 @@
// Original file: null
import type { FieldOptions as _google_protobuf_FieldOptions, FieldOptions__Output as _google_protobuf_FieldOptions__Output } from '../../google/protobuf/FieldOptions';
// Original file: null
export const _google_protobuf_FieldDescriptorProto_Label = {
LABEL_OPTIONAL: 'LABEL_OPTIONAL',
LABEL_REPEATED: 'LABEL_REPEATED',
LABEL_REQUIRED: 'LABEL_REQUIRED',
} as const;
export type _google_protobuf_FieldDescriptorProto_Label =
| 'LABEL_OPTIONAL'
| 1
| 'LABEL_REPEATED'
| 3
| 'LABEL_REQUIRED'
| 2
export type _google_protobuf_FieldDescriptorProto_Label__Output = typeof _google_protobuf_FieldDescriptorProto_Label[keyof typeof _google_protobuf_FieldDescriptorProto_Label]
// Original file: null
export const _google_protobuf_FieldDescriptorProto_Type = {
TYPE_DOUBLE: 'TYPE_DOUBLE',
TYPE_FLOAT: 'TYPE_FLOAT',
TYPE_INT64: 'TYPE_INT64',
TYPE_UINT64: 'TYPE_UINT64',
TYPE_INT32: 'TYPE_INT32',
TYPE_FIXED64: 'TYPE_FIXED64',
TYPE_FIXED32: 'TYPE_FIXED32',
TYPE_BOOL: 'TYPE_BOOL',
TYPE_STRING: 'TYPE_STRING',
TYPE_GROUP: 'TYPE_GROUP',
TYPE_MESSAGE: 'TYPE_MESSAGE',
TYPE_BYTES: 'TYPE_BYTES',
TYPE_UINT32: 'TYPE_UINT32',
TYPE_ENUM: 'TYPE_ENUM',
TYPE_SFIXED32: 'TYPE_SFIXED32',
TYPE_SFIXED64: 'TYPE_SFIXED64',
TYPE_SINT32: 'TYPE_SINT32',
TYPE_SINT64: 'TYPE_SINT64',
} as const;
export type _google_protobuf_FieldDescriptorProto_Type =
| 'TYPE_DOUBLE'
| 1
| 'TYPE_FLOAT'
| 2
| 'TYPE_INT64'
| 3
| 'TYPE_UINT64'
| 4
| 'TYPE_INT32'
| 5
| 'TYPE_FIXED64'
| 6
| 'TYPE_FIXED32'
| 7
| 'TYPE_BOOL'
| 8
| 'TYPE_STRING'
| 9
| 'TYPE_GROUP'
| 10
| 'TYPE_MESSAGE'
| 11
| 'TYPE_BYTES'
| 12
| 'TYPE_UINT32'
| 13
| 'TYPE_ENUM'
| 14
| 'TYPE_SFIXED32'
| 15
| 'TYPE_SFIXED64'
| 16
| 'TYPE_SINT32'
| 17
| 'TYPE_SINT64'
| 18
export type _google_protobuf_FieldDescriptorProto_Type__Output = typeof _google_protobuf_FieldDescriptorProto_Type[keyof typeof _google_protobuf_FieldDescriptorProto_Type]
export interface FieldDescriptorProto {
'name'?: (string);
'extendee'?: (string);
'number'?: (number);
'label'?: (_google_protobuf_FieldDescriptorProto_Label);
'type'?: (_google_protobuf_FieldDescriptorProto_Type);
'typeName'?: (string);
'defaultValue'?: (string);
'options'?: (_google_protobuf_FieldOptions | null);
'oneofIndex'?: (number);
'jsonName'?: (string);
'proto3Optional'?: (boolean);
}
export interface FieldDescriptorProto__Output {
'name': (string);
'extendee': (string);
'number': (number);
'label': (_google_protobuf_FieldDescriptorProto_Label__Output);
'type': (_google_protobuf_FieldDescriptorProto_Type__Output);
'typeName': (string);
'defaultValue': (string);
'options': (_google_protobuf_FieldOptions__Output | null);
'oneofIndex': (number);
'jsonName': (string);
'proto3Optional': (boolean);
}

View File

@@ -0,0 +1,165 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules';
import type { Edition as _google_protobuf_Edition, Edition__Output as _google_protobuf_Edition__Output } from '../../google/protobuf/Edition';
// Original file: null
export const _google_protobuf_FieldOptions_CType = {
STRING: 'STRING',
CORD: 'CORD',
STRING_PIECE: 'STRING_PIECE',
} as const;
export type _google_protobuf_FieldOptions_CType =
| 'STRING'
| 0
| 'CORD'
| 1
| 'STRING_PIECE'
| 2
export type _google_protobuf_FieldOptions_CType__Output = typeof _google_protobuf_FieldOptions_CType[keyof typeof _google_protobuf_FieldOptions_CType]
export interface _google_protobuf_FieldOptions_EditionDefault {
'edition'?: (_google_protobuf_Edition);
'value'?: (string);
}
export interface _google_protobuf_FieldOptions_EditionDefault__Output {
'edition': (_google_protobuf_Edition__Output);
'value': (string);
}
export interface _google_protobuf_FieldOptions_FeatureSupport {
'editionIntroduced'?: (_google_protobuf_Edition);
'editionDeprecated'?: (_google_protobuf_Edition);
'deprecationWarning'?: (string);
'editionRemoved'?: (_google_protobuf_Edition);
}
export interface _google_protobuf_FieldOptions_FeatureSupport__Output {
'editionIntroduced': (_google_protobuf_Edition__Output);
'editionDeprecated': (_google_protobuf_Edition__Output);
'deprecationWarning': (string);
'editionRemoved': (_google_protobuf_Edition__Output);
}
// Original file: null
export const _google_protobuf_FieldOptions_JSType = {
JS_NORMAL: 'JS_NORMAL',
JS_STRING: 'JS_STRING',
JS_NUMBER: 'JS_NUMBER',
} as const;
export type _google_protobuf_FieldOptions_JSType =
| 'JS_NORMAL'
| 0
| 'JS_STRING'
| 1
| 'JS_NUMBER'
| 2
export type _google_protobuf_FieldOptions_JSType__Output = typeof _google_protobuf_FieldOptions_JSType[keyof typeof _google_protobuf_FieldOptions_JSType]
// Original file: null
export const _google_protobuf_FieldOptions_OptionRetention = {
RETENTION_UNKNOWN: 'RETENTION_UNKNOWN',
RETENTION_RUNTIME: 'RETENTION_RUNTIME',
RETENTION_SOURCE: 'RETENTION_SOURCE',
} as const;
export type _google_protobuf_FieldOptions_OptionRetention =
| 'RETENTION_UNKNOWN'
| 0
| 'RETENTION_RUNTIME'
| 1
| 'RETENTION_SOURCE'
| 2
export type _google_protobuf_FieldOptions_OptionRetention__Output = typeof _google_protobuf_FieldOptions_OptionRetention[keyof typeof _google_protobuf_FieldOptions_OptionRetention]
// Original file: null
export const _google_protobuf_FieldOptions_OptionTargetType = {
TARGET_TYPE_UNKNOWN: 'TARGET_TYPE_UNKNOWN',
TARGET_TYPE_FILE: 'TARGET_TYPE_FILE',
TARGET_TYPE_EXTENSION_RANGE: 'TARGET_TYPE_EXTENSION_RANGE',
TARGET_TYPE_MESSAGE: 'TARGET_TYPE_MESSAGE',
TARGET_TYPE_FIELD: 'TARGET_TYPE_FIELD',
TARGET_TYPE_ONEOF: 'TARGET_TYPE_ONEOF',
TARGET_TYPE_ENUM: 'TARGET_TYPE_ENUM',
TARGET_TYPE_ENUM_ENTRY: 'TARGET_TYPE_ENUM_ENTRY',
TARGET_TYPE_SERVICE: 'TARGET_TYPE_SERVICE',
TARGET_TYPE_METHOD: 'TARGET_TYPE_METHOD',
} as const;
export type _google_protobuf_FieldOptions_OptionTargetType =
| 'TARGET_TYPE_UNKNOWN'
| 0
| 'TARGET_TYPE_FILE'
| 1
| 'TARGET_TYPE_EXTENSION_RANGE'
| 2
| 'TARGET_TYPE_MESSAGE'
| 3
| 'TARGET_TYPE_FIELD'
| 4
| 'TARGET_TYPE_ONEOF'
| 5
| 'TARGET_TYPE_ENUM'
| 6
| 'TARGET_TYPE_ENUM_ENTRY'
| 7
| 'TARGET_TYPE_SERVICE'
| 8
| 'TARGET_TYPE_METHOD'
| 9
export type _google_protobuf_FieldOptions_OptionTargetType__Output = typeof _google_protobuf_FieldOptions_OptionTargetType[keyof typeof _google_protobuf_FieldOptions_OptionTargetType]
export interface FieldOptions {
'ctype'?: (_google_protobuf_FieldOptions_CType);
'packed'?: (boolean);
'deprecated'?: (boolean);
'lazy'?: (boolean);
'jstype'?: (_google_protobuf_FieldOptions_JSType);
/**
* @deprecated
*/
'weak'?: (boolean);
'unverifiedLazy'?: (boolean);
'debugRedact'?: (boolean);
'retention'?: (_google_protobuf_FieldOptions_OptionRetention);
'targets'?: (_google_protobuf_FieldOptions_OptionTargetType)[];
'editionDefaults'?: (_google_protobuf_FieldOptions_EditionDefault)[];
'features'?: (_google_protobuf_FeatureSet | null);
'featureSupport'?: (_google_protobuf_FieldOptions_FeatureSupport | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
'.validate.rules'?: (_validate_FieldRules | null);
}
export interface FieldOptions__Output {
'ctype': (_google_protobuf_FieldOptions_CType__Output);
'packed': (boolean);
'deprecated': (boolean);
'lazy': (boolean);
'jstype': (_google_protobuf_FieldOptions_JSType__Output);
/**
* @deprecated
*/
'weak': (boolean);
'unverifiedLazy': (boolean);
'debugRedact': (boolean);
'retention': (_google_protobuf_FieldOptions_OptionRetention__Output);
'targets': (_google_protobuf_FieldOptions_OptionTargetType__Output)[];
'editionDefaults': (_google_protobuf_FieldOptions_EditionDefault__Output)[];
'features': (_google_protobuf_FeatureSet__Output | null);
'featureSupport': (_google_protobuf_FieldOptions_FeatureSupport__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
'.validate.rules': (_validate_FieldRules__Output | null);
}

View File

@@ -0,0 +1,43 @@
// Original file: null
import type { DescriptorProto as _google_protobuf_DescriptorProto, DescriptorProto__Output as _google_protobuf_DescriptorProto__Output } from '../../google/protobuf/DescriptorProto';
import type { EnumDescriptorProto as _google_protobuf_EnumDescriptorProto, EnumDescriptorProto__Output as _google_protobuf_EnumDescriptorProto__Output } from '../../google/protobuf/EnumDescriptorProto';
import type { ServiceDescriptorProto as _google_protobuf_ServiceDescriptorProto, ServiceDescriptorProto__Output as _google_protobuf_ServiceDescriptorProto__Output } from '../../google/protobuf/ServiceDescriptorProto';
import type { FieldDescriptorProto as _google_protobuf_FieldDescriptorProto, FieldDescriptorProto__Output as _google_protobuf_FieldDescriptorProto__Output } from '../../google/protobuf/FieldDescriptorProto';
import type { FileOptions as _google_protobuf_FileOptions, FileOptions__Output as _google_protobuf_FileOptions__Output } from '../../google/protobuf/FileOptions';
import type { SourceCodeInfo as _google_protobuf_SourceCodeInfo, SourceCodeInfo__Output as _google_protobuf_SourceCodeInfo__Output } from '../../google/protobuf/SourceCodeInfo';
import type { Edition as _google_protobuf_Edition, Edition__Output as _google_protobuf_Edition__Output } from '../../google/protobuf/Edition';
export interface FileDescriptorProto {
'name'?: (string);
'package'?: (string);
'dependency'?: (string)[];
'messageType'?: (_google_protobuf_DescriptorProto)[];
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
'service'?: (_google_protobuf_ServiceDescriptorProto)[];
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
'options'?: (_google_protobuf_FileOptions | null);
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo | null);
'publicDependency'?: (number)[];
'weakDependency'?: (number)[];
'syntax'?: (string);
'edition'?: (_google_protobuf_Edition);
'optionDependency'?: (string)[];
}
export interface FileDescriptorProto__Output {
'name': (string);
'package': (string);
'dependency': (string)[];
'messageType': (_google_protobuf_DescriptorProto__Output)[];
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
'service': (_google_protobuf_ServiceDescriptorProto__Output)[];
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
'options': (_google_protobuf_FileOptions__Output | null);
'sourceCodeInfo': (_google_protobuf_SourceCodeInfo__Output | null);
'publicDependency': (number)[];
'weakDependency': (number)[];
'syntax': (string);
'edition': (_google_protobuf_Edition__Output);
'optionDependency': (string)[];
}

View File

@@ -0,0 +1,11 @@
// Original file: null
import type { FileDescriptorProto as _google_protobuf_FileDescriptorProto, FileDescriptorProto__Output as _google_protobuf_FileDescriptorProto__Output } from '../../google/protobuf/FileDescriptorProto';
export interface FileDescriptorSet {
'file'?: (_google_protobuf_FileDescriptorProto)[];
}
export interface FileDescriptorSet__Output {
'file': (_google_protobuf_FileDescriptorProto__Output)[];
}

View File

@@ -0,0 +1,76 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
// Original file: null
export const _google_protobuf_FileOptions_OptimizeMode = {
SPEED: 'SPEED',
CODE_SIZE: 'CODE_SIZE',
LITE_RUNTIME: 'LITE_RUNTIME',
} as const;
export type _google_protobuf_FileOptions_OptimizeMode =
| 'SPEED'
| 1
| 'CODE_SIZE'
| 2
| 'LITE_RUNTIME'
| 3
export type _google_protobuf_FileOptions_OptimizeMode__Output = typeof _google_protobuf_FileOptions_OptimizeMode[keyof typeof _google_protobuf_FileOptions_OptimizeMode]
export interface FileOptions {
'javaPackage'?: (string);
'javaOuterClassname'?: (string);
'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode);
'javaMultipleFiles'?: (boolean);
'goPackage'?: (string);
'ccGenericServices'?: (boolean);
'javaGenericServices'?: (boolean);
'pyGenericServices'?: (boolean);
/**
* @deprecated
*/
'javaGenerateEqualsAndHash'?: (boolean);
'deprecated'?: (boolean);
'javaStringCheckUtf8'?: (boolean);
'ccEnableArenas'?: (boolean);
'objcClassPrefix'?: (string);
'csharpNamespace'?: (string);
'swiftPrefix'?: (string);
'phpClassPrefix'?: (string);
'phpNamespace'?: (string);
'phpMetadataNamespace'?: (string);
'rubyPackage'?: (string);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface FileOptions__Output {
'javaPackage': (string);
'javaOuterClassname': (string);
'optimizeFor': (_google_protobuf_FileOptions_OptimizeMode__Output);
'javaMultipleFiles': (boolean);
'goPackage': (string);
'ccGenericServices': (boolean);
'javaGenericServices': (boolean);
'pyGenericServices': (boolean);
/**
* @deprecated
*/
'javaGenerateEqualsAndHash': (boolean);
'deprecated': (boolean);
'javaStringCheckUtf8': (boolean);
'ccEnableArenas': (boolean);
'objcClassPrefix': (string);
'csharpNamespace': (string);
'swiftPrefix': (string);
'phpClassPrefix': (string);
'phpNamespace': (string);
'phpMetadataNamespace': (string);
'rubyPackage': (string);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface FloatValue {
'value'?: (number | string);
}
export interface FloatValue__Output {
'value': (number);
}

View File

@@ -0,0 +1,44 @@
// Original file: null
export interface _google_protobuf_GeneratedCodeInfo_Annotation {
'path'?: (number)[];
'sourceFile'?: (string);
'begin'?: (number);
'end'?: (number);
'semantic'?: (_google_protobuf_GeneratedCodeInfo_Annotation_Semantic);
}
export interface _google_protobuf_GeneratedCodeInfo_Annotation__Output {
'path': (number)[];
'sourceFile': (string);
'begin': (number);
'end': (number);
'semantic': (_google_protobuf_GeneratedCodeInfo_Annotation_Semantic__Output);
}
// Original file: null
export const _google_protobuf_GeneratedCodeInfo_Annotation_Semantic = {
NONE: 'NONE',
SET: 'SET',
ALIAS: 'ALIAS',
} as const;
export type _google_protobuf_GeneratedCodeInfo_Annotation_Semantic =
| 'NONE'
| 0
| 'SET'
| 1
| 'ALIAS'
| 2
export type _google_protobuf_GeneratedCodeInfo_Annotation_Semantic__Output = typeof _google_protobuf_GeneratedCodeInfo_Annotation_Semantic[keyof typeof _google_protobuf_GeneratedCodeInfo_Annotation_Semantic]
export interface GeneratedCodeInfo {
'annotation'?: (_google_protobuf_GeneratedCodeInfo_Annotation)[];
}
export interface GeneratedCodeInfo__Output {
'annotation': (_google_protobuf_GeneratedCodeInfo_Annotation__Output)[];
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface Int32Value {
'value'?: (number);
}
export interface Int32Value__Output {
'value': (number);
}

View File

@@ -0,0 +1,11 @@
// Original file: null
import type { Long } from '@grpc/proto-loader';
export interface Int64Value {
'value'?: (number | string | Long);
}
export interface Int64Value__Output {
'value': (string);
}

View File

@@ -0,0 +1,32 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface MessageOptions {
'messageSetWireFormat'?: (boolean);
'noStandardDescriptorAccessor'?: (boolean);
'deprecated'?: (boolean);
'mapEntry'?: (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
'.validate.disabled'?: (boolean);
}
export interface MessageOptions__Output {
'messageSetWireFormat': (boolean);
'noStandardDescriptorAccessor': (boolean);
'deprecated': (boolean);
'mapEntry': (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
'.validate.disabled': (boolean);
}

View File

@@ -0,0 +1,21 @@
// Original file: null
import type { MethodOptions as _google_protobuf_MethodOptions, MethodOptions__Output as _google_protobuf_MethodOptions__Output } from '../../google/protobuf/MethodOptions';
export interface MethodDescriptorProto {
'name'?: (string);
'inputType'?: (string);
'outputType'?: (string);
'options'?: (_google_protobuf_MethodOptions | null);
'clientStreaming'?: (boolean);
'serverStreaming'?: (boolean);
}
export interface MethodDescriptorProto__Output {
'name': (string);
'inputType': (string);
'outputType': (string);
'options': (_google_protobuf_MethodOptions__Output | null);
'clientStreaming': (boolean);
'serverStreaming': (boolean);
}

View File

@@ -0,0 +1,36 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
// Original file: null
export const _google_protobuf_MethodOptions_IdempotencyLevel = {
IDEMPOTENCY_UNKNOWN: 'IDEMPOTENCY_UNKNOWN',
NO_SIDE_EFFECTS: 'NO_SIDE_EFFECTS',
IDEMPOTENT: 'IDEMPOTENT',
} as const;
export type _google_protobuf_MethodOptions_IdempotencyLevel =
| 'IDEMPOTENCY_UNKNOWN'
| 0
| 'NO_SIDE_EFFECTS'
| 1
| 'IDEMPOTENT'
| 2
export type _google_protobuf_MethodOptions_IdempotencyLevel__Output = typeof _google_protobuf_MethodOptions_IdempotencyLevel[keyof typeof _google_protobuf_MethodOptions_IdempotencyLevel]
export interface MethodOptions {
'deprecated'?: (boolean);
'idempotencyLevel'?: (_google_protobuf_MethodOptions_IdempotencyLevel);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface MethodOptions__Output {
'deprecated': (boolean);
'idempotencyLevel': (_google_protobuf_MethodOptions_IdempotencyLevel__Output);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,13 @@
// Original file: null
import type { OneofOptions as _google_protobuf_OneofOptions, OneofOptions__Output as _google_protobuf_OneofOptions__Output } from '../../google/protobuf/OneofOptions';
export interface OneofDescriptorProto {
'name'?: (string);
'options'?: (_google_protobuf_OneofOptions | null);
}
export interface OneofDescriptorProto__Output {
'name': (string);
'options': (_google_protobuf_OneofOptions__Output | null);
}

View File

@@ -0,0 +1,16 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface OneofOptions {
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
'.validate.required'?: (boolean);
}
export interface OneofOptions__Output {
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
'.validate.required': (boolean);
}

View File

@@ -0,0 +1,16 @@
// Original file: null
import type { MethodDescriptorProto as _google_protobuf_MethodDescriptorProto, MethodDescriptorProto__Output as _google_protobuf_MethodDescriptorProto__Output } from '../../google/protobuf/MethodDescriptorProto';
import type { ServiceOptions as _google_protobuf_ServiceOptions, ServiceOptions__Output as _google_protobuf_ServiceOptions__Output } from '../../google/protobuf/ServiceOptions';
export interface ServiceDescriptorProto {
'name'?: (string);
'method'?: (_google_protobuf_MethodDescriptorProto)[];
'options'?: (_google_protobuf_ServiceOptions | null);
}
export interface ServiceDescriptorProto__Output {
'name': (string);
'method': (_google_protobuf_MethodDescriptorProto__Output)[];
'options': (_google_protobuf_ServiceOptions__Output | null);
}

View File

@@ -0,0 +1,16 @@
// Original file: null
import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';
export interface ServiceOptions {
'deprecated'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}
export interface ServiceOptions__Output {
'deprecated': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}

View File

@@ -0,0 +1,26 @@
// Original file: null
export interface _google_protobuf_SourceCodeInfo_Location {
'path'?: (number)[];
'span'?: (number)[];
'leadingComments'?: (string);
'trailingComments'?: (string);
'leadingDetachedComments'?: (string)[];
}
export interface _google_protobuf_SourceCodeInfo_Location__Output {
'path': (number)[];
'span': (number)[];
'leadingComments': (string);
'trailingComments': (string);
'leadingDetachedComments': (string)[];
}
export interface SourceCodeInfo {
'location'?: (_google_protobuf_SourceCodeInfo_Location)[];
}
export interface SourceCodeInfo__Output {
'location': (_google_protobuf_SourceCodeInfo_Location__Output)[];
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface StringValue {
'value'?: (string);
}
export interface StringValue__Output {
'value': (string);
}

View File

@@ -0,0 +1,17 @@
// Original file: null
export const SymbolVisibility = {
VISIBILITY_UNSET: 'VISIBILITY_UNSET',
VISIBILITY_LOCAL: 'VISIBILITY_LOCAL',
VISIBILITY_EXPORT: 'VISIBILITY_EXPORT',
} as const;
export type SymbolVisibility =
| 'VISIBILITY_UNSET'
| 0
| 'VISIBILITY_LOCAL'
| 1
| 'VISIBILITY_EXPORT'
| 2
export type SymbolVisibility__Output = typeof SymbolVisibility[keyof typeof SymbolVisibility]

View File

@@ -0,0 +1,13 @@
// Original file: null
import type { Long } from '@grpc/proto-loader';
export interface Timestamp {
'seconds'?: (number | string | Long);
'nanos'?: (number);
}
export interface Timestamp__Output {
'seconds': (string);
'nanos': (number);
}

View File

@@ -0,0 +1,10 @@
// Original file: null
export interface UInt32Value {
'value'?: (number);
}
export interface UInt32Value__Output {
'value': (number);
}

View File

@@ -0,0 +1,11 @@
// Original file: null
import type { Long } from '@grpc/proto-loader';
export interface UInt64Value {
'value'?: (number | string | Long);
}
export interface UInt64Value__Output {
'value': (string);
}

View File

@@ -0,0 +1,33 @@
// Original file: null
import type { Long } from '@grpc/proto-loader';
export interface _google_protobuf_UninterpretedOption_NamePart {
'namePart'?: (string);
'isExtension'?: (boolean);
}
export interface _google_protobuf_UninterpretedOption_NamePart__Output {
'namePart': (string);
'isExtension': (boolean);
}
export interface UninterpretedOption {
'name'?: (_google_protobuf_UninterpretedOption_NamePart)[];
'identifierValue'?: (string);
'positiveIntValue'?: (number | string | Long);
'negativeIntValue'?: (number | string | Long);
'doubleValue'?: (number | string);
'stringValue'?: (Buffer | Uint8Array | string);
'aggregateValue'?: (string);
}
export interface UninterpretedOption__Output {
'name': (_google_protobuf_UninterpretedOption_NamePart__Output)[];
'identifierValue': (string);
'positiveIntValue': (string);
'negativeIntValue': (string);
'doubleValue': (number);
'stringValue': (Buffer);
'aggregateValue': (string);
}

View File

@@ -0,0 +1,89 @@
// Original file: proto/channelz.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
/**
* An address type not included above.
*/
export interface _grpc_channelz_v1_Address_OtherAddress {
/**
* The human readable version of the value. This value should be set.
*/
'name'?: (string);
/**
* The actual address message.
*/
'value'?: (_google_protobuf_Any | null);
}
/**
* An address type not included above.
*/
export interface _grpc_channelz_v1_Address_OtherAddress__Output {
/**
* The human readable version of the value. This value should be set.
*/
'name': (string);
/**
* The actual address message.
*/
'value': (_google_protobuf_Any__Output | null);
}
export interface _grpc_channelz_v1_Address_TcpIpAddress {
/**
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
* bytes in length.
*/
'ip_address'?: (Buffer | Uint8Array | string);
/**
* 0-64k, or -1 if not appropriate.
*/
'port'?: (number);
}
export interface _grpc_channelz_v1_Address_TcpIpAddress__Output {
/**
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
* bytes in length.
*/
'ip_address': (Buffer);
/**
* 0-64k, or -1 if not appropriate.
*/
'port': (number);
}
/**
* A Unix Domain Socket address.
*/
export interface _grpc_channelz_v1_Address_UdsAddress {
'filename'?: (string);
}
/**
* A Unix Domain Socket address.
*/
export interface _grpc_channelz_v1_Address_UdsAddress__Output {
'filename': (string);
}
/**
* Address represents the address used to create the socket.
*/
export interface Address {
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress | null);
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress | null);
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress | null);
'address'?: "tcpip_address"|"uds_address"|"other_address";
}
/**
* Address represents the address used to create the socket.
*/
export interface Address__Output {
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress__Output | null);
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress__Output | null);
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress__Output | null);
'address'?: "tcpip_address"|"uds_address"|"other_address";
}

View File

@@ -0,0 +1,68 @@
// Original file: proto/channelz.proto
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData';
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
/**
* Channel is a logical grouping of channels, subchannels, and sockets.
*/
export interface Channel {
/**
* The identifier for this channel. This should bet set.
*/
'ref'?: (_grpc_channelz_v1_ChannelRef | null);
/**
* Data specific to this channel.
*/
'data'?: (_grpc_channelz_v1_ChannelData | null);
/**
* There are no ordering guarantees on the order of channel refs.
* There may not be cycles in the ref graph.
* A channel ref may be present in more than one channel or subchannel.
*/
'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[];
/**
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
* There are no ordering guarantees on the order of subchannel refs.
* There may not be cycles in the ref graph.
* A sub channel ref may be present in more than one channel or subchannel.
*/
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[];
/**
* There are no ordering guarantees on the order of sockets.
*/
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
}
/**
* Channel is a logical grouping of channels, subchannels, and sockets.
*/
export interface Channel__Output {
/**
* The identifier for this channel. This should bet set.
*/
'ref': (_grpc_channelz_v1_ChannelRef__Output | null);
/**
* Data specific to this channel.
*/
'data': (_grpc_channelz_v1_ChannelData__Output | null);
/**
* There are no ordering guarantees on the order of channel refs.
* There may not be cycles in the ref graph.
* A channel ref may be present in more than one channel or subchannel.
*/
'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[];
/**
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
* There are no ordering guarantees on the order of subchannel refs.
* There may not be cycles in the ref graph.
* A sub channel ref may be present in more than one channel or subchannel.
*/
'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[];
/**
* There are no ordering guarantees on the order of sockets.
*/
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
}

View File

@@ -0,0 +1,45 @@
// Original file: proto/channelz.proto
// Original file: proto/channelz.proto
export const _grpc_channelz_v1_ChannelConnectivityState_State = {
UNKNOWN: 'UNKNOWN',
IDLE: 'IDLE',
CONNECTING: 'CONNECTING',
READY: 'READY',
TRANSIENT_FAILURE: 'TRANSIENT_FAILURE',
SHUTDOWN: 'SHUTDOWN',
} as const;
export type _grpc_channelz_v1_ChannelConnectivityState_State =
| 'UNKNOWN'
| 0
| 'IDLE'
| 1
| 'CONNECTING'
| 2
| 'READY'
| 3
| 'TRANSIENT_FAILURE'
| 4
| 'SHUTDOWN'
| 5
export type _grpc_channelz_v1_ChannelConnectivityState_State__Output = typeof _grpc_channelz_v1_ChannelConnectivityState_State[keyof typeof _grpc_channelz_v1_ChannelConnectivityState_State]
/**
* These come from the specified states in this document:
* https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
*/
export interface ChannelConnectivityState {
'state'?: (_grpc_channelz_v1_ChannelConnectivityState_State);
}
/**
* These come from the specified states in this document:
* https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
*/
export interface ChannelConnectivityState__Output {
'state': (_grpc_channelz_v1_ChannelConnectivityState_State__Output);
}

View File

@@ -0,0 +1,76 @@
// Original file: proto/channelz.proto
import type { ChannelConnectivityState as _grpc_channelz_v1_ChannelConnectivityState, ChannelConnectivityState__Output as _grpc_channelz_v1_ChannelConnectivityState__Output } from '../../../grpc/channelz/v1/ChannelConnectivityState';
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { Long } from '@grpc/proto-loader';
/**
* Channel data is data related to a specific Channel or Subchannel.
*/
export interface ChannelData {
/**
* The connectivity state of the channel or subchannel. Implementations
* should always set this.
*/
'state'?: (_grpc_channelz_v1_ChannelConnectivityState | null);
/**
* The target this channel originally tried to connect to. May be absent
*/
'target'?: (string);
/**
* A trace of recent events on the channel. May be absent.
*/
'trace'?: (_grpc_channelz_v1_ChannelTrace | null);
/**
* The number of calls started on the channel
*/
'calls_started'?: (number | string | Long);
/**
* The number of calls that have completed with an OK status
*/
'calls_succeeded'?: (number | string | Long);
/**
* The number of calls that have completed with a non-OK status
*/
'calls_failed'?: (number | string | Long);
/**
* The last time a call was started on the channel.
*/
'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null);
}
/**
* Channel data is data related to a specific Channel or Subchannel.
*/
export interface ChannelData__Output {
/**
* The connectivity state of the channel or subchannel. Implementations
* should always set this.
*/
'state': (_grpc_channelz_v1_ChannelConnectivityState__Output | null);
/**
* The target this channel originally tried to connect to. May be absent
*/
'target': (string);
/**
* A trace of recent events on the channel. May be absent.
*/
'trace': (_grpc_channelz_v1_ChannelTrace__Output | null);
/**
* The number of calls started on the channel
*/
'calls_started': (string);
/**
* The number of calls that have completed with an OK status
*/
'calls_succeeded': (string);
/**
* The number of calls that have completed with a non-OK status
*/
'calls_failed': (string);
/**
* The last time a call was started on the channel.
*/
'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null);
}

View File

@@ -0,0 +1,31 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
/**
* ChannelRef is a reference to a Channel.
*/
export interface ChannelRef {
/**
* The globally unique id for this channel. Must be a positive number.
*/
'channel_id'?: (number | string | Long);
/**
* An optional name associated with the channel.
*/
'name'?: (string);
}
/**
* ChannelRef is a reference to a Channel.
*/
export interface ChannelRef__Output {
/**
* The globally unique id for this channel. Must be a positive number.
*/
'channel_id': (string);
/**
* An optional name associated with the channel.
*/
'name': (string);
}

View File

@@ -0,0 +1,45 @@
// Original file: proto/channelz.proto
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { ChannelTraceEvent as _grpc_channelz_v1_ChannelTraceEvent, ChannelTraceEvent__Output as _grpc_channelz_v1_ChannelTraceEvent__Output } from '../../../grpc/channelz/v1/ChannelTraceEvent';
import type { Long } from '@grpc/proto-loader';
/**
* ChannelTrace represents the recent events that have occurred on the channel.
*/
export interface ChannelTrace {
/**
* Number of events ever logged in this tracing object. This can differ from
* events.size() because events can be overwritten or garbage collected by
* implementations.
*/
'num_events_logged'?: (number | string | Long);
/**
* Time that this channel was created.
*/
'creation_timestamp'?: (_google_protobuf_Timestamp | null);
/**
* List of events that have occurred on this channel.
*/
'events'?: (_grpc_channelz_v1_ChannelTraceEvent)[];
}
/**
* ChannelTrace represents the recent events that have occurred on the channel.
*/
export interface ChannelTrace__Output {
/**
* Number of events ever logged in this tracing object. This can differ from
* events.size() because events can be overwritten or garbage collected by
* implementations.
*/
'num_events_logged': (string);
/**
* Time that this channel was created.
*/
'creation_timestamp': (_google_protobuf_Timestamp__Output | null);
/**
* List of events that have occurred on this channel.
*/
'events': (_grpc_channelz_v1_ChannelTraceEvent__Output)[];
}

View File

@@ -0,0 +1,91 @@
// Original file: proto/channelz.proto
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
// Original file: proto/channelz.proto
/**
* The supported severity levels of trace events.
*/
export const _grpc_channelz_v1_ChannelTraceEvent_Severity = {
CT_UNKNOWN: 'CT_UNKNOWN',
CT_INFO: 'CT_INFO',
CT_WARNING: 'CT_WARNING',
CT_ERROR: 'CT_ERROR',
} as const;
/**
* The supported severity levels of trace events.
*/
export type _grpc_channelz_v1_ChannelTraceEvent_Severity =
| 'CT_UNKNOWN'
| 0
| 'CT_INFO'
| 1
| 'CT_WARNING'
| 2
| 'CT_ERROR'
| 3
/**
* The supported severity levels of trace events.
*/
export type _grpc_channelz_v1_ChannelTraceEvent_Severity__Output = typeof _grpc_channelz_v1_ChannelTraceEvent_Severity[keyof typeof _grpc_channelz_v1_ChannelTraceEvent_Severity]
/**
* A trace event is an interesting thing that happened to a channel or
* subchannel, such as creation, address resolution, subchannel creation, etc.
*/
export interface ChannelTraceEvent {
/**
* High level description of the event.
*/
'description'?: (string);
/**
* the severity of the trace event
*/
'severity'?: (_grpc_channelz_v1_ChannelTraceEvent_Severity);
/**
* When this event occurred.
*/
'timestamp'?: (_google_protobuf_Timestamp | null);
'channel_ref'?: (_grpc_channelz_v1_ChannelRef | null);
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef | null);
/**
* ref of referenced channel or subchannel.
* Optional, only present if this event refers to a child object. For example,
* this field would be filled if this trace event was for a subchannel being
* created.
*/
'child_ref'?: "channel_ref"|"subchannel_ref";
}
/**
* A trace event is an interesting thing that happened to a channel or
* subchannel, such as creation, address resolution, subchannel creation, etc.
*/
export interface ChannelTraceEvent__Output {
/**
* High level description of the event.
*/
'description': (string);
/**
* the severity of the trace event
*/
'severity': (_grpc_channelz_v1_ChannelTraceEvent_Severity__Output);
/**
* When this event occurred.
*/
'timestamp': (_google_protobuf_Timestamp__Output | null);
'channel_ref'?: (_grpc_channelz_v1_ChannelRef__Output | null);
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef__Output | null);
/**
* ref of referenced channel or subchannel.
* Optional, only present if this event refers to a child object. For example,
* this field would be filled if this trace event was for a subchannel being
* created.
*/
'child_ref'?: "channel_ref"|"subchannel_ref";
}

View File

@@ -0,0 +1,178 @@
// Original file: proto/channelz.proto
import type * as grpc from '../../../../index'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { GetChannelRequest as _grpc_channelz_v1_GetChannelRequest, GetChannelRequest__Output as _grpc_channelz_v1_GetChannelRequest__Output } from '../../../grpc/channelz/v1/GetChannelRequest';
import type { GetChannelResponse as _grpc_channelz_v1_GetChannelResponse, GetChannelResponse__Output as _grpc_channelz_v1_GetChannelResponse__Output } from '../../../grpc/channelz/v1/GetChannelResponse';
import type { GetServerRequest as _grpc_channelz_v1_GetServerRequest, GetServerRequest__Output as _grpc_channelz_v1_GetServerRequest__Output } from '../../../grpc/channelz/v1/GetServerRequest';
import type { GetServerResponse as _grpc_channelz_v1_GetServerResponse, GetServerResponse__Output as _grpc_channelz_v1_GetServerResponse__Output } from '../../../grpc/channelz/v1/GetServerResponse';
import type { GetServerSocketsRequest as _grpc_channelz_v1_GetServerSocketsRequest, GetServerSocketsRequest__Output as _grpc_channelz_v1_GetServerSocketsRequest__Output } from '../../../grpc/channelz/v1/GetServerSocketsRequest';
import type { GetServerSocketsResponse as _grpc_channelz_v1_GetServerSocketsResponse, GetServerSocketsResponse__Output as _grpc_channelz_v1_GetServerSocketsResponse__Output } from '../../../grpc/channelz/v1/GetServerSocketsResponse';
import type { GetServersRequest as _grpc_channelz_v1_GetServersRequest, GetServersRequest__Output as _grpc_channelz_v1_GetServersRequest__Output } from '../../../grpc/channelz/v1/GetServersRequest';
import type { GetServersResponse as _grpc_channelz_v1_GetServersResponse, GetServersResponse__Output as _grpc_channelz_v1_GetServersResponse__Output } from '../../../grpc/channelz/v1/GetServersResponse';
import type { GetSocketRequest as _grpc_channelz_v1_GetSocketRequest, GetSocketRequest__Output as _grpc_channelz_v1_GetSocketRequest__Output } from '../../../grpc/channelz/v1/GetSocketRequest';
import type { GetSocketResponse as _grpc_channelz_v1_GetSocketResponse, GetSocketResponse__Output as _grpc_channelz_v1_GetSocketResponse__Output } from '../../../grpc/channelz/v1/GetSocketResponse';
import type { GetSubchannelRequest as _grpc_channelz_v1_GetSubchannelRequest, GetSubchannelRequest__Output as _grpc_channelz_v1_GetSubchannelRequest__Output } from '../../../grpc/channelz/v1/GetSubchannelRequest';
import type { GetSubchannelResponse as _grpc_channelz_v1_GetSubchannelResponse, GetSubchannelResponse__Output as _grpc_channelz_v1_GetSubchannelResponse__Output } from '../../../grpc/channelz/v1/GetSubchannelResponse';
import type { GetTopChannelsRequest as _grpc_channelz_v1_GetTopChannelsRequest, GetTopChannelsRequest__Output as _grpc_channelz_v1_GetTopChannelsRequest__Output } from '../../../grpc/channelz/v1/GetTopChannelsRequest';
import type { GetTopChannelsResponse as _grpc_channelz_v1_GetTopChannelsResponse, GetTopChannelsResponse__Output as _grpc_channelz_v1_GetTopChannelsResponse__Output } from '../../../grpc/channelz/v1/GetTopChannelsResponse';
/**
* Channelz is a service exposed by gRPC servers that provides detailed debug
* information.
*/
export interface ChannelzClient extends grpc.Client {
/**
* Returns a single Channel, or else a NOT_FOUND code.
*/
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Server, or else a NOT_FOUND code.
*/
GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Server, or else a NOT_FOUND code.
*/
getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all server sockets that exist in the process.
*/
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all server sockets that exist in the process.
*/
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all servers that exist in the process.
*/
GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all servers that exist in the process.
*/
getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Socket or else a NOT_FOUND code.
*/
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Socket or else a NOT_FOUND code.
*/
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Subchannel, or else a NOT_FOUND code.
*/
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
/**
* Returns a single Subchannel, or else a NOT_FOUND code.
*/
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all root channels (i.e. channels the application has directly
* created). This does not include subchannels nor non-top level channels.
*/
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets all root channels (i.e. channels the application has directly
* created). This does not include subchannels nor non-top level channels.
*/
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
}
/**
* Channelz is a service exposed by gRPC servers that provides detailed debug
* information.
*/
export interface ChannelzHandlers extends grpc.UntypedServiceImplementation {
/**
* Returns a single Channel, or else a NOT_FOUND code.
*/
GetChannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse>;
/**
* Returns a single Server, or else a NOT_FOUND code.
*/
GetServer: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse>;
/**
* Gets all server sockets that exist in the process.
*/
GetServerSockets: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse>;
/**
* Gets all servers that exist in the process.
*/
GetServers: grpc.handleUnaryCall<_grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse>;
/**
* Returns a single Socket or else a NOT_FOUND code.
*/
GetSocket: grpc.handleUnaryCall<_grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse>;
/**
* Returns a single Subchannel, or else a NOT_FOUND code.
*/
GetSubchannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse>;
/**
* Gets all root channels (i.e. channels the application has directly
* created). This does not include subchannels nor non-top level channels.
*/
GetTopChannels: grpc.handleUnaryCall<_grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse>;
}
export interface ChannelzDefinition extends grpc.ServiceDefinition {
GetChannel: MethodDefinition<_grpc_channelz_v1_GetChannelRequest, _grpc_channelz_v1_GetChannelResponse, _grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse__Output>
GetServer: MethodDefinition<_grpc_channelz_v1_GetServerRequest, _grpc_channelz_v1_GetServerResponse, _grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse__Output>
GetServerSockets: MethodDefinition<_grpc_channelz_v1_GetServerSocketsRequest, _grpc_channelz_v1_GetServerSocketsResponse, _grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse__Output>
GetServers: MethodDefinition<_grpc_channelz_v1_GetServersRequest, _grpc_channelz_v1_GetServersResponse, _grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse__Output>
GetSocket: MethodDefinition<_grpc_channelz_v1_GetSocketRequest, _grpc_channelz_v1_GetSocketResponse, _grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse__Output>
GetSubchannel: MethodDefinition<_grpc_channelz_v1_GetSubchannelRequest, _grpc_channelz_v1_GetSubchannelResponse, _grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse__Output>
GetTopChannels: MethodDefinition<_grpc_channelz_v1_GetTopChannelsRequest, _grpc_channelz_v1_GetTopChannelsResponse, _grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse__Output>
}

View File

@@ -0,0 +1,17 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetChannelRequest {
/**
* channel_id is the identifier of the specific channel to get.
*/
'channel_id'?: (number | string | Long);
}
export interface GetChannelRequest__Output {
/**
* channel_id is the identifier of the specific channel to get.
*/
'channel_id': (string);
}

View File

@@ -0,0 +1,19 @@
// Original file: proto/channelz.proto
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel';
export interface GetChannelResponse {
/**
* The Channel that corresponds to the requested channel_id. This field
* should be set.
*/
'channel'?: (_grpc_channelz_v1_Channel | null);
}
export interface GetChannelResponse__Output {
/**
* The Channel that corresponds to the requested channel_id. This field
* should be set.
*/
'channel': (_grpc_channelz_v1_Channel__Output | null);
}

View File

@@ -0,0 +1,17 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetServerRequest {
/**
* server_id is the identifier of the specific server to get.
*/
'server_id'?: (number | string | Long);
}
export interface GetServerRequest__Output {
/**
* server_id is the identifier of the specific server to get.
*/
'server_id': (string);
}

View File

@@ -0,0 +1,19 @@
// Original file: proto/channelz.proto
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server';
export interface GetServerResponse {
/**
* The Server that corresponds to the requested server_id. This field
* should be set.
*/
'server'?: (_grpc_channelz_v1_Server | null);
}
export interface GetServerResponse__Output {
/**
* The Server that corresponds to the requested server_id. This field
* should be set.
*/
'server': (_grpc_channelz_v1_Server__Output | null);
}

View File

@@ -0,0 +1,39 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetServerSocketsRequest {
'server_id'?: (number | string | Long);
/**
* start_socket_id indicates that only sockets at or above this id should be
* included in the results.
* To request the first page, this must be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_socket_id'?: (number | string | Long);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results'?: (number | string | Long);
}
export interface GetServerSocketsRequest__Output {
'server_id': (string);
/**
* start_socket_id indicates that only sockets at or above this id should be
* included in the results.
* To request the first page, this must be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_socket_id': (string);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results': (string);
}

View File

@@ -0,0 +1,33 @@
// Original file: proto/channelz.proto
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
export interface GetServerSocketsResponse {
/**
* list of socket refs that the connection detail service knows about. Sorted in
* ascending socket_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
/**
* If set, indicates that the list of sockets is the final list. Requesting
* more sockets will only return more if they are created after this RPC
* completes.
*/
'end'?: (boolean);
}
export interface GetServerSocketsResponse__Output {
/**
* list of socket refs that the connection detail service knows about. Sorted in
* ascending socket_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
/**
* If set, indicates that the list of sockets is the final list. Requesting
* more sockets will only return more if they are created after this RPC
* completes.
*/
'end': (boolean);
}

View File

@@ -0,0 +1,37 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetServersRequest {
/**
* start_server_id indicates that only servers at or above this id should be
* included in the results.
* To request the first page, this must be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_server_id'?: (number | string | Long);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results'?: (number | string | Long);
}
export interface GetServersRequest__Output {
/**
* start_server_id indicates that only servers at or above this id should be
* included in the results.
* To request the first page, this must be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_server_id': (string);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results': (string);
}

View File

@@ -0,0 +1,33 @@
// Original file: proto/channelz.proto
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server';
export interface GetServersResponse {
/**
* list of servers that the connection detail service knows about. Sorted in
* ascending server_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'server'?: (_grpc_channelz_v1_Server)[];
/**
* If set, indicates that the list of servers is the final list. Requesting
* more servers will only return more if they are created after this RPC
* completes.
*/
'end'?: (boolean);
}
export interface GetServersResponse__Output {
/**
* list of servers that the connection detail service knows about. Sorted in
* ascending server_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'server': (_grpc_channelz_v1_Server__Output)[];
/**
* If set, indicates that the list of servers is the final list. Requesting
* more servers will only return more if they are created after this RPC
* completes.
*/
'end': (boolean);
}

View File

@@ -0,0 +1,29 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetSocketRequest {
/**
* socket_id is the identifier of the specific socket to get.
*/
'socket_id'?: (number | string | Long);
/**
* If true, the response will contain only high level information
* that is inexpensive to obtain. Fields thay may be omitted are
* documented.
*/
'summary'?: (boolean);
}
export interface GetSocketRequest__Output {
/**
* socket_id is the identifier of the specific socket to get.
*/
'socket_id': (string);
/**
* If true, the response will contain only high level information
* that is inexpensive to obtain. Fields thay may be omitted are
* documented.
*/
'summary': (boolean);
}

View File

@@ -0,0 +1,19 @@
// Original file: proto/channelz.proto
import type { Socket as _grpc_channelz_v1_Socket, Socket__Output as _grpc_channelz_v1_Socket__Output } from '../../../grpc/channelz/v1/Socket';
export interface GetSocketResponse {
/**
* The Socket that corresponds to the requested socket_id. This field
* should be set.
*/
'socket'?: (_grpc_channelz_v1_Socket | null);
}
export interface GetSocketResponse__Output {
/**
* The Socket that corresponds to the requested socket_id. This field
* should be set.
*/
'socket': (_grpc_channelz_v1_Socket__Output | null);
}

View File

@@ -0,0 +1,17 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetSubchannelRequest {
/**
* subchannel_id is the identifier of the specific subchannel to get.
*/
'subchannel_id'?: (number | string | Long);
}
export interface GetSubchannelRequest__Output {
/**
* subchannel_id is the identifier of the specific subchannel to get.
*/
'subchannel_id': (string);
}

View File

@@ -0,0 +1,19 @@
// Original file: proto/channelz.proto
import type { Subchannel as _grpc_channelz_v1_Subchannel, Subchannel__Output as _grpc_channelz_v1_Subchannel__Output } from '../../../grpc/channelz/v1/Subchannel';
export interface GetSubchannelResponse {
/**
* The Subchannel that corresponds to the requested subchannel_id. This
* field should be set.
*/
'subchannel'?: (_grpc_channelz_v1_Subchannel | null);
}
export interface GetSubchannelResponse__Output {
/**
* The Subchannel that corresponds to the requested subchannel_id. This
* field should be set.
*/
'subchannel': (_grpc_channelz_v1_Subchannel__Output | null);
}

View File

@@ -0,0 +1,37 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
export interface GetTopChannelsRequest {
/**
* start_channel_id indicates that only channels at or above this id should be
* included in the results.
* To request the first page, this should be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_channel_id'?: (number | string | Long);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results'?: (number | string | Long);
}
export interface GetTopChannelsRequest__Output {
/**
* start_channel_id indicates that only channels at or above this id should be
* included in the results.
* To request the first page, this should be set to 0. To request
* subsequent pages, the client generates this value by adding 1 to
* the highest seen result ID.
*/
'start_channel_id': (string);
/**
* If non-zero, the server will return a page of results containing
* at most this many items. If zero, the server will choose a
* reasonable page size. Must never be negative.
*/
'max_results': (string);
}

View File

@@ -0,0 +1,33 @@
// Original file: proto/channelz.proto
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel';
export interface GetTopChannelsResponse {
/**
* list of channels that the connection detail service knows about. Sorted in
* ascending channel_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'channel'?: (_grpc_channelz_v1_Channel)[];
/**
* If set, indicates that the list of channels is the final list. Requesting
* more channels can only return more if they are created after this RPC
* completes.
*/
'end'?: (boolean);
}
export interface GetTopChannelsResponse__Output {
/**
* list of channels that the connection detail service knows about. Sorted in
* ascending channel_id order.
* Must contain at least 1 result, otherwise 'end' must be true.
*/
'channel': (_grpc_channelz_v1_Channel__Output)[];
/**
* If set, indicates that the list of channels is the final list. Requesting
* more channels can only return more if they are created after this RPC
* completes.
*/
'end': (boolean);
}

View File

@@ -0,0 +1,87 @@
// Original file: proto/channelz.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
export interface _grpc_channelz_v1_Security_OtherSecurity {
/**
* The human readable version of the value.
*/
'name'?: (string);
/**
* The actual security details message.
*/
'value'?: (_google_protobuf_Any | null);
}
export interface _grpc_channelz_v1_Security_OtherSecurity__Output {
/**
* The human readable version of the value.
*/
'name': (string);
/**
* The actual security details message.
*/
'value': (_google_protobuf_Any__Output | null);
}
export interface _grpc_channelz_v1_Security_Tls {
/**
* The cipher suite name in the RFC 4346 format:
* https://tools.ietf.org/html/rfc4346#appendix-C
*/
'standard_name'?: (string);
/**
* Some other way to describe the cipher suite if
* the RFC 4346 name is not available.
*/
'other_name'?: (string);
/**
* the certificate used by this endpoint.
*/
'local_certificate'?: (Buffer | Uint8Array | string);
/**
* the certificate used by the remote endpoint.
*/
'remote_certificate'?: (Buffer | Uint8Array | string);
'cipher_suite'?: "standard_name"|"other_name";
}
export interface _grpc_channelz_v1_Security_Tls__Output {
/**
* The cipher suite name in the RFC 4346 format:
* https://tools.ietf.org/html/rfc4346#appendix-C
*/
'standard_name'?: (string);
/**
* Some other way to describe the cipher suite if
* the RFC 4346 name is not available.
*/
'other_name'?: (string);
/**
* the certificate used by this endpoint.
*/
'local_certificate': (Buffer);
/**
* the certificate used by the remote endpoint.
*/
'remote_certificate': (Buffer);
'cipher_suite'?: "standard_name"|"other_name";
}
/**
* Security represents details about how secure the socket is.
*/
export interface Security {
'tls'?: (_grpc_channelz_v1_Security_Tls | null);
'other'?: (_grpc_channelz_v1_Security_OtherSecurity | null);
'model'?: "tls"|"other";
}
/**
* Security represents details about how secure the socket is.
*/
export interface Security__Output {
'tls'?: (_grpc_channelz_v1_Security_Tls__Output | null);
'other'?: (_grpc_channelz_v1_Security_OtherSecurity__Output | null);
'model'?: "tls"|"other";
}

View File

@@ -0,0 +1,45 @@
// Original file: proto/channelz.proto
import type { ServerRef as _grpc_channelz_v1_ServerRef, ServerRef__Output as _grpc_channelz_v1_ServerRef__Output } from '../../../grpc/channelz/v1/ServerRef';
import type { ServerData as _grpc_channelz_v1_ServerData, ServerData__Output as _grpc_channelz_v1_ServerData__Output } from '../../../grpc/channelz/v1/ServerData';
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
/**
* Server represents a single server. There may be multiple servers in a single
* program.
*/
export interface Server {
/**
* The identifier for a Server. This should be set.
*/
'ref'?: (_grpc_channelz_v1_ServerRef | null);
/**
* The associated data of the Server.
*/
'data'?: (_grpc_channelz_v1_ServerData | null);
/**
* The sockets that the server is listening on. There are no ordering
* guarantees. This may be absent.
*/
'listen_socket'?: (_grpc_channelz_v1_SocketRef)[];
}
/**
* Server represents a single server. There may be multiple servers in a single
* program.
*/
export interface Server__Output {
/**
* The identifier for a Server. This should be set.
*/
'ref': (_grpc_channelz_v1_ServerRef__Output | null);
/**
* The associated data of the Server.
*/
'data': (_grpc_channelz_v1_ServerData__Output | null);
/**
* The sockets that the server is listening on. There are no ordering
* guarantees. This may be absent.
*/
'listen_socket': (_grpc_channelz_v1_SocketRef__Output)[];
}

View File

@@ -0,0 +1,57 @@
// Original file: proto/channelz.proto
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { Long } from '@grpc/proto-loader';
/**
* ServerData is data for a specific Server.
*/
export interface ServerData {
/**
* A trace of recent events on the server. May be absent.
*/
'trace'?: (_grpc_channelz_v1_ChannelTrace | null);
/**
* The number of incoming calls started on the server
*/
'calls_started'?: (number | string | Long);
/**
* The number of incoming calls that have completed with an OK status
*/
'calls_succeeded'?: (number | string | Long);
/**
* The number of incoming calls that have a completed with a non-OK status
*/
'calls_failed'?: (number | string | Long);
/**
* The last time a call was started on the server.
*/
'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null);
}
/**
* ServerData is data for a specific Server.
*/
export interface ServerData__Output {
/**
* A trace of recent events on the server. May be absent.
*/
'trace': (_grpc_channelz_v1_ChannelTrace__Output | null);
/**
* The number of incoming calls started on the server
*/
'calls_started': (string);
/**
* The number of incoming calls that have completed with an OK status
*/
'calls_succeeded': (string);
/**
* The number of incoming calls that have a completed with a non-OK status
*/
'calls_failed': (string);
/**
* The last time a call was started on the server.
*/
'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null);
}

View File

@@ -0,0 +1,31 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
/**
* ServerRef is a reference to a Server.
*/
export interface ServerRef {
/**
* A globally unique identifier for this server. Must be a positive number.
*/
'server_id'?: (number | string | Long);
/**
* An optional name associated with the server.
*/
'name'?: (string);
}
/**
* ServerRef is a reference to a Server.
*/
export interface ServerRef__Output {
/**
* A globally unique identifier for this server. Must be a positive number.
*/
'server_id': (string);
/**
* An optional name associated with the server.
*/
'name': (string);
}

View File

@@ -0,0 +1,70 @@
// Original file: proto/channelz.proto
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
import type { SocketData as _grpc_channelz_v1_SocketData, SocketData__Output as _grpc_channelz_v1_SocketData__Output } from '../../../grpc/channelz/v1/SocketData';
import type { Address as _grpc_channelz_v1_Address, Address__Output as _grpc_channelz_v1_Address__Output } from '../../../grpc/channelz/v1/Address';
import type { Security as _grpc_channelz_v1_Security, Security__Output as _grpc_channelz_v1_Security__Output } from '../../../grpc/channelz/v1/Security';
/**
* Information about an actual connection. Pronounced "sock-ay".
*/
export interface Socket {
/**
* The identifier for the Socket.
*/
'ref'?: (_grpc_channelz_v1_SocketRef | null);
/**
* Data specific to this Socket.
*/
'data'?: (_grpc_channelz_v1_SocketData | null);
/**
* The locally bound address.
*/
'local'?: (_grpc_channelz_v1_Address | null);
/**
* The remote bound address. May be absent.
*/
'remote'?: (_grpc_channelz_v1_Address | null);
/**
* Security details for this socket. May be absent if not available, or
* there is no security on the socket.
*/
'security'?: (_grpc_channelz_v1_Security | null);
/**
* Optional, represents the name of the remote endpoint, if different than
* the original target name.
*/
'remote_name'?: (string);
}
/**
* Information about an actual connection. Pronounced "sock-ay".
*/
export interface Socket__Output {
/**
* The identifier for the Socket.
*/
'ref': (_grpc_channelz_v1_SocketRef__Output | null);
/**
* Data specific to this Socket.
*/
'data': (_grpc_channelz_v1_SocketData__Output | null);
/**
* The locally bound address.
*/
'local': (_grpc_channelz_v1_Address__Output | null);
/**
* The remote bound address. May be absent.
*/
'remote': (_grpc_channelz_v1_Address__Output | null);
/**
* Security details for this socket. May be absent if not available, or
* there is no security on the socket.
*/
'security': (_grpc_channelz_v1_Security__Output | null);
/**
* Optional, represents the name of the remote endpoint, if different than
* the original target name.
*/
'remote_name': (string);
}

View File

@@ -0,0 +1,150 @@
// Original file: proto/channelz.proto
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { Int64Value as _google_protobuf_Int64Value, Int64Value__Output as _google_protobuf_Int64Value__Output } from '../../../google/protobuf/Int64Value';
import type { SocketOption as _grpc_channelz_v1_SocketOption, SocketOption__Output as _grpc_channelz_v1_SocketOption__Output } from '../../../grpc/channelz/v1/SocketOption';
import type { Long } from '@grpc/proto-loader';
/**
* SocketData is data associated for a specific Socket. The fields present
* are specific to the implementation, so there may be minor differences in
* the semantics. (e.g. flow control windows)
*/
export interface SocketData {
/**
* The number of streams that have been started.
*/
'streams_started'?: (number | string | Long);
/**
* The number of streams that have ended successfully:
* On client side, received frame with eos bit set;
* On server side, sent frame with eos bit set.
*/
'streams_succeeded'?: (number | string | Long);
/**
* The number of streams that have ended unsuccessfully:
* On client side, ended without receiving frame with eos bit set;
* On server side, ended without sending frame with eos bit set.
*/
'streams_failed'?: (number | string | Long);
/**
* The number of grpc messages successfully sent on this socket.
*/
'messages_sent'?: (number | string | Long);
/**
* The number of grpc messages received on this socket.
*/
'messages_received'?: (number | string | Long);
/**
* The number of keep alives sent. This is typically implemented with HTTP/2
* ping messages.
*/
'keep_alives_sent'?: (number | string | Long);
/**
* The last time a stream was created by this endpoint. Usually unset for
* servers.
*/
'last_local_stream_created_timestamp'?: (_google_protobuf_Timestamp | null);
/**
* The last time a stream was created by the remote endpoint. Usually unset
* for clients.
*/
'last_remote_stream_created_timestamp'?: (_google_protobuf_Timestamp | null);
/**
* The last time a message was sent by this endpoint.
*/
'last_message_sent_timestamp'?: (_google_protobuf_Timestamp | null);
/**
* The last time a message was received by this endpoint.
*/
'last_message_received_timestamp'?: (_google_protobuf_Timestamp | null);
/**
* The amount of window, granted to the local endpoint by the remote endpoint.
* This may be slightly out of date due to network latency. This does NOT
* include stream level or TCP level flow control info.
*/
'local_flow_control_window'?: (_google_protobuf_Int64Value | null);
/**
* The amount of window, granted to the remote endpoint by the local endpoint.
* This may be slightly out of date due to network latency. This does NOT
* include stream level or TCP level flow control info.
*/
'remote_flow_control_window'?: (_google_protobuf_Int64Value | null);
/**
* Socket options set on this socket. May be absent if 'summary' is set
* on GetSocketRequest.
*/
'option'?: (_grpc_channelz_v1_SocketOption)[];
}
/**
* SocketData is data associated for a specific Socket. The fields present
* are specific to the implementation, so there may be minor differences in
* the semantics. (e.g. flow control windows)
*/
export interface SocketData__Output {
/**
* The number of streams that have been started.
*/
'streams_started': (string);
/**
* The number of streams that have ended successfully:
* On client side, received frame with eos bit set;
* On server side, sent frame with eos bit set.
*/
'streams_succeeded': (string);
/**
* The number of streams that have ended unsuccessfully:
* On client side, ended without receiving frame with eos bit set;
* On server side, ended without sending frame with eos bit set.
*/
'streams_failed': (string);
/**
* The number of grpc messages successfully sent on this socket.
*/
'messages_sent': (string);
/**
* The number of grpc messages received on this socket.
*/
'messages_received': (string);
/**
* The number of keep alives sent. This is typically implemented with HTTP/2
* ping messages.
*/
'keep_alives_sent': (string);
/**
* The last time a stream was created by this endpoint. Usually unset for
* servers.
*/
'last_local_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null);
/**
* The last time a stream was created by the remote endpoint. Usually unset
* for clients.
*/
'last_remote_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null);
/**
* The last time a message was sent by this endpoint.
*/
'last_message_sent_timestamp': (_google_protobuf_Timestamp__Output | null);
/**
* The last time a message was received by this endpoint.
*/
'last_message_received_timestamp': (_google_protobuf_Timestamp__Output | null);
/**
* The amount of window, granted to the local endpoint by the remote endpoint.
* This may be slightly out of date due to network latency. This does NOT
* include stream level or TCP level flow control info.
*/
'local_flow_control_window': (_google_protobuf_Int64Value__Output | null);
/**
* The amount of window, granted to the remote endpoint by the local endpoint.
* This may be slightly out of date due to network latency. This does NOT
* include stream level or TCP level flow control info.
*/
'remote_flow_control_window': (_google_protobuf_Int64Value__Output | null);
/**
* Socket options set on this socket. May be absent if 'summary' is set
* on GetSocketRequest.
*/
'option': (_grpc_channelz_v1_SocketOption__Output)[];
}

View File

@@ -0,0 +1,47 @@
// Original file: proto/channelz.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
/**
* SocketOption represents socket options for a socket. Specifically, these
* are the options returned by getsockopt().
*/
export interface SocketOption {
/**
* The full name of the socket option. Typically this will be the upper case
* name, such as "SO_REUSEPORT".
*/
'name'?: (string);
/**
* The human readable value of this socket option. At least one of value or
* additional will be set.
*/
'value'?: (string);
/**
* Additional data associated with the socket option. At least one of value
* or additional will be set.
*/
'additional'?: (_google_protobuf_Any | null);
}
/**
* SocketOption represents socket options for a socket. Specifically, these
* are the options returned by getsockopt().
*/
export interface SocketOption__Output {
/**
* The full name of the socket option. Typically this will be the upper case
* name, such as "SO_REUSEPORT".
*/
'name': (string);
/**
* The human readable value of this socket option. At least one of value or
* additional will be set.
*/
'value': (string);
/**
* Additional data associated with the socket option. At least one of value
* or additional will be set.
*/
'additional': (_google_protobuf_Any__Output | null);
}

View File

@@ -0,0 +1,33 @@
// Original file: proto/channelz.proto
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration';
/**
* For use with SocketOption's additional field. This is primarily used for
* SO_LINGER.
*/
export interface SocketOptionLinger {
/**
* active maps to `struct linger.l_onoff`
*/
'active'?: (boolean);
/**
* duration maps to `struct linger.l_linger`
*/
'duration'?: (_google_protobuf_Duration | null);
}
/**
* For use with SocketOption's additional field. This is primarily used for
* SO_LINGER.
*/
export interface SocketOptionLinger__Output {
/**
* active maps to `struct linger.l_onoff`
*/
'active': (boolean);
/**
* duration maps to `struct linger.l_linger`
*/
'duration': (_google_protobuf_Duration__Output | null);
}

View File

@@ -0,0 +1,74 @@
// Original file: proto/channelz.proto
/**
* For use with SocketOption's additional field. Tcp info for
* SOL_TCP and TCP_INFO.
*/
export interface SocketOptionTcpInfo {
'tcpi_state'?: (number);
'tcpi_ca_state'?: (number);
'tcpi_retransmits'?: (number);
'tcpi_probes'?: (number);
'tcpi_backoff'?: (number);
'tcpi_options'?: (number);
'tcpi_snd_wscale'?: (number);
'tcpi_rcv_wscale'?: (number);
'tcpi_rto'?: (number);
'tcpi_ato'?: (number);
'tcpi_snd_mss'?: (number);
'tcpi_rcv_mss'?: (number);
'tcpi_unacked'?: (number);
'tcpi_sacked'?: (number);
'tcpi_lost'?: (number);
'tcpi_retrans'?: (number);
'tcpi_fackets'?: (number);
'tcpi_last_data_sent'?: (number);
'tcpi_last_ack_sent'?: (number);
'tcpi_last_data_recv'?: (number);
'tcpi_last_ack_recv'?: (number);
'tcpi_pmtu'?: (number);
'tcpi_rcv_ssthresh'?: (number);
'tcpi_rtt'?: (number);
'tcpi_rttvar'?: (number);
'tcpi_snd_ssthresh'?: (number);
'tcpi_snd_cwnd'?: (number);
'tcpi_advmss'?: (number);
'tcpi_reordering'?: (number);
}
/**
* For use with SocketOption's additional field. Tcp info for
* SOL_TCP and TCP_INFO.
*/
export interface SocketOptionTcpInfo__Output {
'tcpi_state': (number);
'tcpi_ca_state': (number);
'tcpi_retransmits': (number);
'tcpi_probes': (number);
'tcpi_backoff': (number);
'tcpi_options': (number);
'tcpi_snd_wscale': (number);
'tcpi_rcv_wscale': (number);
'tcpi_rto': (number);
'tcpi_ato': (number);
'tcpi_snd_mss': (number);
'tcpi_rcv_mss': (number);
'tcpi_unacked': (number);
'tcpi_sacked': (number);
'tcpi_lost': (number);
'tcpi_retrans': (number);
'tcpi_fackets': (number);
'tcpi_last_data_sent': (number);
'tcpi_last_ack_sent': (number);
'tcpi_last_data_recv': (number);
'tcpi_last_ack_recv': (number);
'tcpi_pmtu': (number);
'tcpi_rcv_ssthresh': (number);
'tcpi_rtt': (number);
'tcpi_rttvar': (number);
'tcpi_snd_ssthresh': (number);
'tcpi_snd_cwnd': (number);
'tcpi_advmss': (number);
'tcpi_reordering': (number);
}

View File

@@ -0,0 +1,19 @@
// Original file: proto/channelz.proto
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration';
/**
* For use with SocketOption's additional field. This is primarily used for
* SO_RCVTIMEO and SO_SNDTIMEO
*/
export interface SocketOptionTimeout {
'duration'?: (_google_protobuf_Duration | null);
}
/**
* For use with SocketOption's additional field. This is primarily used for
* SO_RCVTIMEO and SO_SNDTIMEO
*/
export interface SocketOptionTimeout__Output {
'duration': (_google_protobuf_Duration__Output | null);
}

View File

@@ -0,0 +1,31 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
/**
* SocketRef is a reference to a Socket.
*/
export interface SocketRef {
/**
* The globally unique id for this socket. Must be a positive number.
*/
'socket_id'?: (number | string | Long);
/**
* An optional name associated with the socket.
*/
'name'?: (string);
}
/**
* SocketRef is a reference to a Socket.
*/
export interface SocketRef__Output {
/**
* The globally unique id for this socket. Must be a positive number.
*/
'socket_id': (string);
/**
* An optional name associated with the socket.
*/
'name': (string);
}

View File

@@ -0,0 +1,70 @@
// Original file: proto/channelz.proto
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData';
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
/**
* Subchannel is a logical grouping of channels, subchannels, and sockets.
* A subchannel is load balanced over by it's ancestor
*/
export interface Subchannel {
/**
* The identifier for this channel.
*/
'ref'?: (_grpc_channelz_v1_SubchannelRef | null);
/**
* Data specific to this channel.
*/
'data'?: (_grpc_channelz_v1_ChannelData | null);
/**
* There are no ordering guarantees on the order of channel refs.
* There may not be cycles in the ref graph.
* A channel ref may be present in more than one channel or subchannel.
*/
'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[];
/**
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
* There are no ordering guarantees on the order of subchannel refs.
* There may not be cycles in the ref graph.
* A sub channel ref may be present in more than one channel or subchannel.
*/
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[];
/**
* There are no ordering guarantees on the order of sockets.
*/
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
}
/**
* Subchannel is a logical grouping of channels, subchannels, and sockets.
* A subchannel is load balanced over by it's ancestor
*/
export interface Subchannel__Output {
/**
* The identifier for this channel.
*/
'ref': (_grpc_channelz_v1_SubchannelRef__Output | null);
/**
* Data specific to this channel.
*/
'data': (_grpc_channelz_v1_ChannelData__Output | null);
/**
* There are no ordering guarantees on the order of channel refs.
* There may not be cycles in the ref graph.
* A channel ref may be present in more than one channel or subchannel.
*/
'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[];
/**
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
* There are no ordering guarantees on the order of subchannel refs.
* There may not be cycles in the ref graph.
* A sub channel ref may be present in more than one channel or subchannel.
*/
'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[];
/**
* There are no ordering guarantees on the order of sockets.
*/
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
}

View File

@@ -0,0 +1,31 @@
// Original file: proto/channelz.proto
import type { Long } from '@grpc/proto-loader';
/**
* SubchannelRef is a reference to a Subchannel.
*/
export interface SubchannelRef {
/**
* The globally unique id for this subchannel. Must be a positive number.
*/
'subchannel_id'?: (number | string | Long);
/**
* An optional name associated with the subchannel.
*/
'name'?: (string);
}
/**
* SubchannelRef is a reference to a Subchannel.
*/
export interface SubchannelRef__Output {
/**
* The globally unique id for this subchannel. Must be a positive number.
*/
'subchannel_id': (string);
/**
* An optional name associated with the subchannel.
*/
'name': (string);
}

Some files were not shown because too many files have changed in this diff Show More