UNPKG

@grpc.ts/core

Version:
535 lines (486 loc) 17.8 kB
'use strict'; var tls = require('tls'); var grpcJs = require('@grpc/grpc-js'); var util = require('util'); var protoLoader = require('@grpc/proto-loader'); var require$$0 = require('google-protobuf'); class GrpcTimestamp { nanos; seconds; } var compressionAlgorithms = {}; var hasRequiredCompressionAlgorithms; function requireCompressionAlgorithms () { if (hasRequiredCompressionAlgorithms) return compressionAlgorithms; hasRequiredCompressionAlgorithms = 1; /* * 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. * */ Object.defineProperty(compressionAlgorithms, "__esModule", { value: true }); compressionAlgorithms.CompressionAlgorithms = void 0; var CompressionAlgorithms; (function (CompressionAlgorithms) { CompressionAlgorithms[CompressionAlgorithms["identity"] = 0] = "identity"; CompressionAlgorithms[CompressionAlgorithms["deflate"] = 1] = "deflate"; CompressionAlgorithms[CompressionAlgorithms["gzip"] = 2] = "gzip"; })(CompressionAlgorithms || (compressionAlgorithms.CompressionAlgorithms = CompressionAlgorithms = {})); return compressionAlgorithms; } var compressionAlgorithmsExports = requireCompressionAlgorithms(); function toSnakeCase(source) { return source.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`); } function convertChannelOptions({ maxSessionMemory, defaultCompressionAlgorithm, ...options }) { const opts = Object.entries(options).reduce((result, [key, value]) => { result[`grpc.${toSnakeCase(key)}`] = value; return result; }, {}); return { ...opts, 'grpc-node.max_session_memory': maxSessionMemory, 'grpc.default_compression_algorithm': defaultCompressionAlgorithm ? compressionAlgorithmsExports.CompressionAlgorithms[defaultCompressionAlgorithm] : undefined, }; } function extractPackage(grpcObject, packagePath) { if (!packagePath) { return grpcObject; } const paths = packagePath.split('.'); let object = grpcObject; paths.forEach((p) => { object = object[p]; }); return object; } function isGrpcService(obj) { return (typeof obj == 'function' && Object.prototype.hasOwnProperty.call(obj, 'service') && Object.prototype.hasOwnProperty.call(obj, 'serviceName')); } async function loadPackage({ package: packageInfo, packageDefinitionOptions, }) { if (!Array.isArray(packageInfo)) { packageInfo = [packageInfo]; } const packageDefinitions = await Promise.all(packageInfo.map(async ({ protoPath }) => { return protoLoader.load(protoPath, packageDefinitionOptions); })); const packages = packageInfo; // to fix typescript typing for the code below return packageDefinitions.reduce((result, packageDef, index) => { const packageObject = grpcJs.loadPackageDefinition(packageDef); const { packageName = '' } = packages[index]; const rawPackage = extractPackage(packageObject, packageName); const packageServices = { ...result[packageName], }; Object.entries(rawPackage).forEach(([k, v]) => { if (!isGrpcService(v)) { return; } packageServices[k] = v; }); Object.assign(result, { [packageName]: packageServices, }); return result; }, {}); } function makeServiceClients({ url, options, packageDefs, credentials, }) { const channelOptions = convertChannelOptions(options); return Object.entries(packageDefs).reduce((result, [packageName, packageServices]) => { const clientServices = Object.entries(packageServices).reduce((services, [serviceName, serviceClient]) => { const client = new serviceClient(url, credentials, channelOptions); services[serviceName] = client; const methodNames = Object.keys(Object.getPrototypeOf(client)).filter((propertyName) => typeof client[propertyName] === 'function'); methodNames.forEach((methodName) => { client[methodName] = util.promisify(client[methodName].bind(client)); }); return services; }, {}); result[packageName] = clientServices; return result; }, {}); } async function createClient({ url, options = {}, credentials: creds, package: packageInfo, packageDefinitionOptions, }) { const packageDefs = await loadPackage({ package: packageInfo, packageDefinitionOptions, }); const clients = makeServiceClients({ url, options, packageDefs, credentials: creds || grpcJs.credentials.createInsecure(), }); const getService = (serviceName, options = {}) => { const { packageName = '' } = options; return clients[packageName]?.[serviceName]; // TODO: fix type }; const close = () => { Object.values(clients).forEach((client) => { Object.values(client).forEach((sc) => { sc.close(); }); }); }; const getPackages = () => { return clients; }; return { close, getService, getPackages, }; } const serviceMethodTracking = {}; async function createServer({ url, options = {}, credentials: creds, package: packageInfo, packageDefinitionOptions, }) { const packageDefs = await loadPackage({ package: packageInfo, packageDefinitionOptions, }); const server = new grpcJs.Server(convertChannelOptions(options)); const bindAsync = util.promisify(server.bindAsync.bind(server)); await bindAsync(url, creds || grpcJs.ServerCredentials.createInsecure()); const addUnaryHandler = (serviceName, rpcName, impl, opts = {}) => { const { package: packageName = '' } = opts; const pkg = packageDefs[packageName]; const { service } = pkg?.[serviceName] || {}; if (!service) { throw `Cannot find service ${serviceName}`; } const key = `${packageName}::${serviceName}::${rpcName}`; if (serviceMethodTracking[key]) { return; } else { serviceMethodTracking[key] = true; } const subName = rpcName.substring(1); const rpcNameUpper = rpcName[0].toUpperCase() + subName; const rpcNameLower = rpcName[0].toLowerCase() + subName; if (!Object.prototype.hasOwnProperty.call(service, rpcNameLower) && !Object.prototype.hasOwnProperty.call(service, rpcNameUpper)) { throw `${serviceName} service does not have ${rpcName} rpc method`; } const implFunc = async (call, callback) => { let alreadyCalled = false; const hofCallback = (err, value) => { alreadyCalled = true; callback(err, value); }; const result = await impl(call.request, call.metadata, call, hofCallback); if (alreadyCalled) { return; } callback(null, result); }; const attrs = service[rpcNameLower] || service[rpcNameUpper]; server.register(attrs.path, implFunc, attrs.responseSerialize, attrs.requestDeserialize, 'unary'); }; return { server, addUnaryHandler, }; } var timestamp_pb = {}; var hasRequiredTimestamp_pb; function requireTimestamp_pb () { if (hasRequiredTimestamp_pb) return timestamp_pb; hasRequiredTimestamp_pb = 1; (function (exports) { // source: google/protobuf/timestamp.proto /** * @fileoverview * @enhanceable * @suppress {missingRequire} reports error on implicit type usages. * @suppress {messageConventions} JS Compiler reports an error if a variable or * field starts with 'MSG_' and isn't a translatable message. * @public */ // GENERATED CODE -- DO NOT EDIT! /* eslint-disable */ // @ts-nocheck var jspb = require$$0; var goog = jspb; var global = (typeof globalThis !== 'undefined' && globalThis) || (typeof window !== 'undefined' && window) || (typeof global !== 'undefined' && global) || (typeof self !== 'undefined' && self) || (function () { return this; }).call(null) || Function('return this')(); goog.exportSymbol('proto.google.protobuf.Timestamp', null, global); /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a * server response, or constructed directly in Javascript. The array is used * in place and becomes part of the constructed object. It is not cloned. * If no data is provided, the constructed object will be empty, but still * valid. * @extends {jspb.Message} * @constructor */ proto.google.protobuf.Timestamp = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; goog.inherits(proto.google.protobuf.Timestamp, jspb.Message); if (goog.DEBUG && !COMPILED) { /** * @public * @override */ proto.google.protobuf.Timestamp.displayName = 'proto.google.protobuf.Timestamp'; } if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto. * Field names that are reserved in JavaScript and will be renamed to pb_name. * Optional fields that are not set will be set to undefined. * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. * For the list of reserved names please see: * net/proto2/compiler/js/internal/generator.cc#kKeyword. * @param {boolean=} opt_includeInstance Deprecated. whether to include the * JSPB instance for transitional soy proto support: * http://goto/soy-param-migration * @return {!Object} */ proto.google.protobuf.Timestamp.prototype.toObject = function(opt_includeInstance) { return proto.google.protobuf.Timestamp.toObject(opt_includeInstance, this); }; /** * Static version of the {@see toObject} method. * @param {boolean|undefined} includeInstance Deprecated. Whether to include * the JSPB instance for transitional soy proto support: * http://goto/soy-param-migration * @param {!proto.google.protobuf.Timestamp} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.google.protobuf.Timestamp.toObject = function(includeInstance, msg) { var obj = { seconds: jspb.Message.getFieldWithDefault(msg, 1, 0), nanos: jspb.Message.getFieldWithDefault(msg, 2, 0) }; if (includeInstance) { obj.$jspbMessageInstance = msg; } return obj; }; } /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. * @return {!proto.google.protobuf.Timestamp} */ proto.google.protobuf.Timestamp.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); var msg = new proto.google.protobuf.Timestamp; return proto.google.protobuf.Timestamp.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. * @param {!proto.google.protobuf.Timestamp} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. * @return {!proto.google.protobuf.Timestamp} */ proto.google.protobuf.Timestamp.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; } var field = reader.getFieldNumber(); switch (field) { case 1: var value = /** @type {number} */ (reader.readInt64()); msg.setSeconds(value); break; case 2: var value = /** @type {number} */ (reader.readInt32()); msg.setNanos(value); break; default: reader.skipField(); break; } } return msg; }; /** * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ proto.google.protobuf.Timestamp.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); proto.google.protobuf.Timestamp.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. * @param {!proto.google.protobuf.Timestamp} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ proto.google.protobuf.Timestamp.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getSeconds(); if (f !== 0) { writer.writeInt64( 1, f ); } f = message.getNanos(); if (f !== 0) { writer.writeInt32( 2, f ); } }; /** * optional int64 seconds = 1; * @return {number} */ proto.google.protobuf.Timestamp.prototype.getSeconds = function() { return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); }; /** * @param {number} value * @return {!proto.google.protobuf.Timestamp} returns this */ proto.google.protobuf.Timestamp.prototype.setSeconds = function(value) { return jspb.Message.setProto3IntField(this, 1, value); }; /** * optional int32 nanos = 2; * @return {number} */ proto.google.protobuf.Timestamp.prototype.getNanos = function() { return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); }; /** * @param {number} value * @return {!proto.google.protobuf.Timestamp} returns this */ proto.google.protobuf.Timestamp.prototype.setNanos = function(value) { return jspb.Message.setProto3IntField(this, 2, value); }; goog.object.extend(exports, proto.google.protobuf); /* This code will be inserted into generated code for * google/protobuf/timestamp.proto. */ /** * Returns a JavaScript 'Date' object corresponding to this Timestamp. * @return {!Date} */ proto.google.protobuf.Timestamp.prototype.toDate = function() { var seconds = this.getSeconds(); var nanos = this.getNanos(); return new Date((seconds * 1000) + (nanos / 1000000)); }; /** * Sets the value of this Timestamp object to be the given Date. * @param {!Date} value The value to set. */ proto.google.protobuf.Timestamp.prototype.fromDate = function(value) { this.setSeconds(Math.floor(value.getTime() / 1000)); this.setNanos(value.getMilliseconds() * 1000000); }; /** * Factory method that returns a Timestamp object with value equal to * the given Date. * @param {!Date} value The value to set. * @return {!proto.google.protobuf.Timestamp} */ proto.google.protobuf.Timestamp.fromDate = function(value) { var timestamp = new proto.google.protobuf.Timestamp(); timestamp.fromDate(value); return timestamp; }; } (timestamp_pb)); return timestamp_pb; } var timestamp_pbExports = requireTimestamp_pb(); function isDate(data) { return data instanceof Date; } function createMetadata(params) { const metadata = new grpcJs.Metadata(); Object.entries(params).forEach(([key, value]) => { metadata.add(key, value); }); return metadata; } function dateToGrpcTimestamp(data) { if (!isDate(data)) { data = new Date(data); } const { nanos, seconds } = timestamp_pbExports.Timestamp.fromDate(data).toObject(); const timestamp = new GrpcTimestamp(); timestamp.nanos = nanos; timestamp.seconds = seconds; return timestamp; } function grpcTimestampToDate(data) { let low; const { nanos, seconds } = data; if (typeof seconds === 'string') { low = parseInt(seconds, 10); } else { low = seconds; } const timestamp = new timestamp_pbExports.Timestamp(); timestamp.setNanos(nanos); timestamp.setSeconds(low); return timestamp.toDate(); } Object.defineProperty(exports, "createSecureContext", { enumerable: true, get: function () { return tls.createSecureContext; } }); Object.defineProperty(exports, "ChannelCredentials", { enumerable: true, get: function () { return grpcJs.ChannelCredentials; } }); Object.defineProperty(exports, "Metadata", { enumerable: true, get: function () { return grpcJs.Metadata; } }); Object.defineProperty(exports, "ServerCredentials", { enumerable: true, get: function () { return grpcJs.ServerCredentials; } }); Object.defineProperty(exports, "StatusBuilder", { enumerable: true, get: function () { return grpcJs.StatusBuilder; } }); Object.defineProperty(exports, "credentials", { enumerable: true, get: function () { return grpcJs.credentials; } }); Object.defineProperty(exports, "status", { enumerable: true, get: function () { return grpcJs.status; } }); exports.GrpcTimestamp = GrpcTimestamp; exports.createClient = createClient; exports.createMetadata = createMetadata; exports.createServer = createServer; exports.dateToGrpcTimestamp = dateToGrpcTimestamp; exports.grpcTimestampToDate = grpcTimestampToDate;