From 8eff962cab608341a6f2fedc640a0e32d96f26e2 Mon Sep 17 00:00:00 2001 From: altaf-creator Date: Sun, 9 Nov 2025 11:15:19 +0800 Subject: pain --- .../node_modules/@grpc/grpc-js/src/metadata.ts | 298 +++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 frontend-old/node_modules/@grpc/grpc-js/src/metadata.ts (limited to 'frontend-old/node_modules/@grpc/grpc-js/src/metadata.ts') diff --git a/frontend-old/node_modules/@grpc/grpc-js/src/metadata.ts b/frontend-old/node_modules/@grpc/grpc-js/src/metadata.ts new file mode 100644 index 0000000..eabd2df --- /dev/null +++ b/frontend-old/node_modules/@grpc/grpc-js/src/metadata.ts @@ -0,0 +1,298 @@ +/* + * 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 http2 from 'http2'; +import { log } from './logging'; +import { LogVerbosity } from './constants'; +import { getErrorMessage } from './error'; +const LEGAL_KEY_REGEX = /^[0-9a-z_.-]+$/; +const LEGAL_NON_BINARY_VALUE_REGEX = /^[ -~]*$/; + +export type MetadataValue = string | Buffer; +export type MetadataObject = Map; + +function isLegalKey(key: string): boolean { + return LEGAL_KEY_REGEX.test(key); +} + +function isLegalNonBinaryValue(value: string): boolean { + return LEGAL_NON_BINARY_VALUE_REGEX.test(value); +} + +function isBinaryKey(key: string): boolean { + return key.endsWith('-bin'); +} + +function isCustomMetadata(key: string): boolean { + return !key.startsWith('grpc-'); +} + +function normalizeKey(key: string): string { + return key.toLowerCase(); +} + +function validate(key: string, value?: MetadataValue): void { + if (!isLegalKey(key)) { + throw new Error('Metadata key "' + key + '" contains illegal characters'); + } + + if (value !== null && value !== undefined) { + if (isBinaryKey(key)) { + if (!Buffer.isBuffer(value)) { + throw new Error("keys that end with '-bin' must have Buffer values"); + } + } else { + if (Buffer.isBuffer(value)) { + throw new Error( + "keys that don't end with '-bin' must have String values" + ); + } + if (!isLegalNonBinaryValue(value)) { + throw new Error( + 'Metadata string value "' + value + '" contains illegal characters' + ); + } + } + } +} + +export interface MetadataOptions { + /* Signal that the request is idempotent. Defaults to false */ + idempotentRequest?: boolean; + /* Signal that the call should not return UNAVAILABLE before it has + * started. Defaults to false. */ + waitForReady?: boolean; + /* Signal that the call is cacheable. GRPC is free to use GET verb. + * Defaults to false */ + cacheableRequest?: boolean; + /* Signal that the initial metadata should be corked. Defaults to false. */ + corked?: boolean; +} + +/** + * A class for storing metadata. Keys are normalized to lowercase ASCII. + */ +export class Metadata { + protected internalRepr: MetadataObject = new Map(); + private options: MetadataOptions; + + constructor(options: MetadataOptions = {}) { + this.options = options; + } + + /** + * Sets the given value for the given key by replacing any other values + * associated with that key. Normalizes the key. + * @param key The key to whose value should be set. + * @param value The value to set. Must be a buffer if and only + * if the normalized key ends with '-bin'. + */ + set(key: string, value: MetadataValue): void { + key = normalizeKey(key); + validate(key, value); + this.internalRepr.set(key, [value]); + } + + /** + * Adds the given value for the given key by appending to a list of previous + * values associated with that key. Normalizes the key. + * @param key The key for which a new value should be appended. + * @param value The value to add. Must be a buffer if and only + * if the normalized key ends with '-bin'. + */ + add(key: string, value: MetadataValue): void { + key = normalizeKey(key); + validate(key, value); + + const existingValue: MetadataValue[] | undefined = + this.internalRepr.get(key); + + if (existingValue === undefined) { + this.internalRepr.set(key, [value]); + } else { + existingValue.push(value); + } + } + + /** + * Removes the given key and any associated values. Normalizes the key. + * @param key The key whose values should be removed. + */ + remove(key: string): void { + key = normalizeKey(key); + // validate(key); + this.internalRepr.delete(key); + } + + /** + * Gets a list of all values associated with the key. Normalizes the key. + * @param key The key whose value should be retrieved. + * @return A list of values associated with the given key. + */ + get(key: string): MetadataValue[] { + key = normalizeKey(key); + // validate(key); + return this.internalRepr.get(key) || []; + } + + /** + * Gets a plain object mapping each key to the first value associated with it. + * This reflects the most common way that people will want to see metadata. + * @return A key/value mapping of the metadata. + */ + getMap(): { [key: string]: MetadataValue } { + const result: { [key: string]: MetadataValue } = {}; + + for (const [key, values] of this.internalRepr) { + if (values.length > 0) { + const v = values[0]; + result[key] = Buffer.isBuffer(v) ? Buffer.from(v) : v; + } + } + return result; + } + + /** + * Clones the metadata object. + * @return The newly cloned object. + */ + clone(): Metadata { + const newMetadata = new Metadata(this.options); + const newInternalRepr = newMetadata.internalRepr; + + for (const [key, value] of this.internalRepr) { + const clonedValue: MetadataValue[] = value.map(v => { + if (Buffer.isBuffer(v)) { + return Buffer.from(v); + } else { + return v; + } + }); + + newInternalRepr.set(key, clonedValue); + } + + return newMetadata; + } + + /** + * Merges all key-value pairs from a given Metadata object into this one. + * If both this object and the given object have values in the same key, + * values from the other Metadata object will be appended to this object's + * values. + * @param other A Metadata object. + */ + merge(other: Metadata): void { + for (const [key, values] of other.internalRepr) { + const mergedValue: MetadataValue[] = ( + this.internalRepr.get(key) || [] + ).concat(values); + + this.internalRepr.set(key, mergedValue); + } + } + + setOptions(options: MetadataOptions) { + this.options = options; + } + + getOptions(): MetadataOptions { + return this.options; + } + + /** + * Creates an OutgoingHttpHeaders object that can be used with the http2 API. + */ + toHttp2Headers(): http2.OutgoingHttpHeaders { + // NOTE: Node <8.9 formats http2 headers incorrectly. + const result: http2.OutgoingHttpHeaders = {}; + + for (const [key, values] of this.internalRepr) { + // We assume that the user's interaction with this object is limited to + // through its public API (i.e. keys and values are already validated). + result[key] = values.map(bufToString); + } + + return result; + } + + /** + * This modifies the behavior of JSON.stringify to show an object + * representation of the metadata map. + */ + toJSON() { + const result: { [key: string]: MetadataValue[] } = {}; + for (const [key, values] of this.internalRepr) { + result[key] = values; + } + return result; + } + + /** + * Returns a new Metadata object based fields in a given IncomingHttpHeaders + * object. + * @param headers An IncomingHttpHeaders object. + */ + static fromHttp2Headers(headers: http2.IncomingHttpHeaders): Metadata { + const result = new Metadata(); + for (const key of Object.keys(headers)) { + // Reserved headers (beginning with `:`) are not valid keys. + if (key.charAt(0) === ':') { + continue; + } + + const values = headers[key]; + + try { + if (isBinaryKey(key)) { + if (Array.isArray(values)) { + values.forEach(value => { + result.add(key, Buffer.from(value, 'base64')); + }); + } else if (values !== undefined) { + if (isCustomMetadata(key)) { + values.split(',').forEach(v => { + result.add(key, Buffer.from(v.trim(), 'base64')); + }); + } else { + result.add(key, Buffer.from(values, 'base64')); + } + } + } else { + if (Array.isArray(values)) { + values.forEach(value => { + result.add(key, value); + }); + } else if (values !== undefined) { + result.add(key, values); + } + } + } catch (error) { + const message = `Failed to add metadata entry ${key}: ${values}. ${getErrorMessage( + error + )}. For more information see https://github.com/grpc/grpc-node/issues/1173`; + log(LogVerbosity.ERROR, message); + } + } + + return result; + } +} + +const bufToString = (val: string | Buffer): string => { + return Buffer.isBuffer(val) ? val.toString('base64') : val; +}; -- cgit v1.2.3