@connectrpc/connect
Advanced tools
@@ -46,3 +46,3 @@ "use strict"; | ||
| function createUnaryFn(transport, method) { | ||
| return function (requestMessage, callback, options) { | ||
| return (requestMessage, callback, options) => { | ||
| const abort = new AbortController(); | ||
@@ -69,3 +69,3 @@ options = wrapSignal(abort, options); | ||
| function createServerStreamingFn(transport, method) { | ||
| return function (input, onResponse, onClose, options) { | ||
| return (input, onResponse, onClose, options) => { | ||
| const abort = new AbortController(); | ||
@@ -72,0 +72,0 @@ async function run() { |
@@ -59,4 +59,4 @@ import { Code } from "./code.js"; | ||
| * - If the value is already a ConnectError, return it as is. | ||
| * - If the value is an AbortError from the fetch API, return the message | ||
| * of the AbortError with code Canceled. | ||
| * - If the value is an AbortError or TimeoutError from the fetch API, return | ||
| * the message of the error with code Canceled. | ||
| * - For other Errors, return the error message with code Unknown by default. | ||
@@ -63,0 +63,0 @@ * - For other values, return the values String representation as a message, |
@@ -56,4 +56,4 @@ "use strict"; | ||
| * - If the value is already a ConnectError, return it as is. | ||
| * - If the value is an AbortError from the fetch API, return the message | ||
| * of the AbortError with code Canceled. | ||
| * - If the value is an AbortError or TimeoutError from the fetch API, return | ||
| * the message of the error with code Canceled. | ||
| * - For other Errors, return the error message with code Unknown by default. | ||
@@ -70,6 +70,5 @@ * - For other values, return the values String representation as a message, | ||
| if (reason instanceof Error) { | ||
| if (reason.name == "AbortError") { | ||
| // Fetch requests can only be canceled with an AbortController. | ||
| // We detect that condition by looking at the name of the raised | ||
| // error object, and translate to the appropriate status code. | ||
| if (reason.name == "AbortError" || reason.name == "TimeoutError") { | ||
| // Fetch requests can only be canceled with an AbortController, | ||
| // or with AbortSignal.timeout(). | ||
| return new ConnectError(reason.message, code_js_1.Code.Canceled); | ||
@@ -76,0 +75,0 @@ } |
@@ -23,6 +23,9 @@ "use strict"; | ||
| function applyInterceptors(next, interceptors) { | ||
| var _a; | ||
| return ((_a = interceptors === null || interceptors === void 0 ? void 0 : interceptors.concat().reverse().reduce( | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-argument | ||
| (n, i) => i(n), next)) !== null && _a !== void 0 ? _a : next); | ||
| if (!interceptors) { | ||
| return next; | ||
| } | ||
| for (const i of interceptors.concat().reverse()) { | ||
| next = i(next); | ||
| } | ||
| return next; | ||
| } |
@@ -71,3 +71,3 @@ "use strict"; | ||
| function createUnaryFn(transport, method) { | ||
| return async function (input, options) { | ||
| return async (input, options) => { | ||
| var _a, _b; | ||
@@ -81,8 +81,6 @@ const response = await transport.unary(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, input, options === null || options === void 0 ? void 0 : options.contextValues); | ||
| function createServerStreamingFn(transport, method) { | ||
| return function (input, options) { | ||
| return handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, (0, async_iterable_js_1.createAsyncIterable)([input]), options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| }; | ||
| return (input, options) => handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, (0, async_iterable_js_1.createAsyncIterable)([input]), options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| } | ||
| function createClientStreamingFn(transport, method) { | ||
| return async function (request, options) { | ||
| return async (request, options) => { | ||
| var _a, e_1, _b, _c; | ||
@@ -121,5 +119,3 @@ var _d, _e; | ||
| function createBiDiStreamingFn(transport, method) { | ||
| return function (request, options) { | ||
| return handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, request, options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| }; | ||
| return (request, options) => handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, request, options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| } | ||
@@ -126,0 +122,0 @@ function handleStreamResponse(stream, options) { |
@@ -25,5 +25,3 @@ "use strict"; | ||
| } | ||
| else { | ||
| return encodeURIComponent(new TextDecoder().decode(message)); | ||
| } | ||
| return encodeURIComponent(new TextDecoder().decode(message)); | ||
| } | ||
@@ -52,5 +50,5 @@ /** | ||
| const url = request.url + query; | ||
| const header = new Headers(request.header); | ||
| // Omit headers that are not used for unary GET requests. | ||
| const header = new Headers(request.header); | ||
| [ | ||
| for (const h of [ | ||
| headers_js_1.headerProtocolVersion, | ||
@@ -61,5 +59,7 @@ headers_js_1.headerContentType, | ||
| headers_js_1.headerUnaryAcceptEncoding, | ||
| ].forEach((h) => header.delete(h)); | ||
| ]) { | ||
| header.delete(h); | ||
| } | ||
| return Object.assign(Object.assign({}, request), { requestMethod: "GET", url, | ||
| header }); | ||
| } |
@@ -43,3 +43,3 @@ "use strict"; | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| result.set(headers_js_1.headerUserAgent, "connect-es/2.0.2"); | ||
| result.set(headers_js_1.headerUserAgent, "connect-es/2.0.3"); | ||
| } | ||
@@ -46,0 +46,0 @@ return result; |
@@ -40,3 +40,3 @@ "use strict"; | ||
| } | ||
| else if (v !== exports.protocolVersion) { | ||
| if (v !== exports.protocolVersion) { | ||
| throw new connect_error_js_1.ConnectError(`${headers_js_1.headerProtocolVersion} must be "${exports.protocolVersion}": got "${v}"`, code_js_1.Code.InvalidArgument); | ||
@@ -56,5 +56,5 @@ } | ||
| } | ||
| else if (v !== `v${exports.protocolVersion}`) { | ||
| if (v !== `v${exports.protocolVersion}`) { | ||
| throw new connect_error_js_1.ConnectError(`${query_params_js_1.paramConnectVersion} must be "v${exports.protocolVersion}": got "${v}"`, code_js_1.Code.InvalidArgument); | ||
| } | ||
| } |
@@ -26,2 +26,3 @@ "use strict"; | ||
| function requestHeader(useBinaryFormat, timeoutMs, userProvidedHeaders, setUserAgent) { | ||
| var _a, _b; | ||
| const result = new Headers(userProvidedHeaders !== null && userProvidedHeaders !== void 0 ? userProvidedHeaders : {}); | ||
@@ -35,8 +36,3 @@ // Note that we do not support the grpc-web-text format. | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| let userAgent = "connect-es/2.0.2"; | ||
| userAgent = result.has(headers_js_1.headerUserAgent) | ||
| ? result.get(headers_js_1.headerUserAgent) | ||
| : result.has(headers_js_1.headerXUserAgent) | ||
| ? result.get(headers_js_1.headerXUserAgent) | ||
| : userAgent; | ||
| const userAgent = (_b = (_a = result.get(headers_js_1.headerUserAgent)) !== null && _a !== void 0 ? _a : result.get(headers_js_1.headerXUserAgent)) !== null && _b !== void 0 ? _b : "connect-es/2.0.3"; | ||
| result.set(headers_js_1.headerXUserAgent, userAgent); | ||
@@ -43,0 +39,0 @@ if (setUserAgent) { |
@@ -1,2 +0,2 @@ | ||
| import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; | ||
| import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; | ||
| import type { Any } from "@bufbuild/protobuf/wkt"; | ||
@@ -3,0 +3,0 @@ import type { Message } from "@bufbuild/protobuf"; |
@@ -17,3 +17,3 @@ "use strict"; | ||
| exports.StatusSchema = exports.file_status = void 0; | ||
| const codegenv1_1 = require("@bufbuild/protobuf/codegenv1"); | ||
| const codegenv2_1 = require("@bufbuild/protobuf/codegenv2"); | ||
| const wkt_1 = require("@bufbuild/protobuf/wkt"); | ||
@@ -23,3 +23,3 @@ /** | ||
| */ | ||
| exports.file_status = (0, codegenv1_1.fileDesc)("CgxzdGF0dXMucHJvdG8SCmdvb2dsZS5ycGMiTgoGU3RhdHVzEgwKBGNvZGUYASABKAUSDwoHbWVzc2FnZRgCIAEoCRIlCgdkZXRhaWxzGAMgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueUJeCg5jb20uZ29vZ2xlLnJwY0ILU3RhdHVzUHJvdG9QAVo3Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy9ycGMvc3RhdHVzO3N0YXR1c6ICA1JQQ2IGcHJvdG8z", [wkt_1.file_google_protobuf_any]); | ||
| exports.file_status = (0, codegenv2_1.fileDesc)("CgxzdGF0dXMucHJvdG8SCmdvb2dsZS5ycGMiTgoGU3RhdHVzEgwKBGNvZGUYASABKAUSDwoHbWVzc2FnZRgCIAEoCRIlCgdkZXRhaWxzGAMgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueUJeCg5jb20uZ29vZ2xlLnJwY0ILU3RhdHVzUHJvdG9QAVo3Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy9ycGMvc3RhdHVzO3N0YXR1c6ICA1JQQ2IGcHJvdG8z", [wkt_1.file_google_protobuf_any]); | ||
| /** | ||
@@ -29,2 +29,2 @@ * Describes the message google.rpc.Status. | ||
| */ | ||
| exports.StatusSchema = (0, codegenv1_1.messageDesc)(exports.file_status, 0); | ||
| exports.StatusSchema = (0, codegenv2_1.messageDesc)(exports.file_status, 0); |
@@ -32,3 +32,3 @@ "use strict"; | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| result.set(headers_js_1.headerUserAgent, "connect-es/2.0.2"); | ||
| result.set(headers_js_1.headerUserAgent, "connect-es/2.0.3"); | ||
| } | ||
@@ -35,0 +35,0 @@ if (timeoutMs !== undefined) { |
@@ -1,2 +0,2 @@ | ||
| import type { EnvelopedMessage } from "./envelope.js"; | ||
| import { type EnvelopedMessage } from "./envelope.js"; | ||
| import type { Serialization } from "./serialization.js"; | ||
@@ -3,0 +3,0 @@ import type { Compression } from "./compression.js"; |
@@ -64,2 +64,3 @@ "use strict"; | ||
| const envelope_js_1 = require("./envelope.js"); | ||
| const envelope_js_2 = require("./envelope.js"); | ||
| const limit_io_js_1 = require("./limit-io.js"); | ||
@@ -73,3 +74,2 @@ function pipeTo(source, ...rest) { | ||
| } | ||
| // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
| // @ts-ignore | ||
@@ -99,3 +99,3 @@ iterable = pipe(iterable, ...transforms, { propagateDownStreamError: false }); | ||
| function sinkAll() { | ||
| return async function (iterable) { | ||
| return async (iterable) => { | ||
| var _a, e_1, _b, _c; | ||
@@ -136,5 +136,3 @@ const all = []; | ||
| function sinkAllBytes(readMaxBytes, lengthHint) { | ||
| return async function (iterable) { | ||
| return await readAllBytes(iterable, readMaxBytes, lengthHint); | ||
| }; | ||
| return async (iterable) => await readAllBytes(iterable, readMaxBytes, lengthHint); | ||
| } | ||
@@ -487,3 +485,3 @@ function pipe(source, ...rest) { | ||
| const env = _c; | ||
| yield yield __await(yield __await((0, envelope_js_1.envelopeCompress)(env, compression, compressMinBytes))); | ||
| yield yield __await(yield __await((0, envelope_js_2.envelopeCompress)(env, compression, compressMinBytes))); | ||
| } | ||
@@ -519,3 +517,3 @@ } | ||
| const env = _c; | ||
| yield yield __await(yield __await((0, envelope_js_1.envelopeDecompress)(env, compression, readMaxBytes))); | ||
| yield yield __await(yield __await((0, envelope_js_2.envelopeDecompress)(env, compression, readMaxBytes))); | ||
| } | ||
@@ -548,3 +546,3 @@ } | ||
| const { flags, data } = _c; | ||
| yield yield __await((0, envelope_js_1.encodeEnvelope)(flags, data)); | ||
| yield yield __await((0, envelope_js_2.encodeEnvelope)(flags, data)); | ||
| } | ||
@@ -574,34 +572,6 @@ } | ||
| function transformSplitEnvelope(readMaxBytes) { | ||
| // append chunk to buffer, returning updated buffer | ||
| function append(buffer, chunk) { | ||
| const n = new Uint8Array(buffer.byteLength + chunk.byteLength); | ||
| n.set(buffer); | ||
| n.set(chunk, buffer.length); | ||
| return n; | ||
| } | ||
| // tuple 0: envelope, or undefined if incomplete | ||
| // tuple 1: remainder of the buffer | ||
| function shiftEnvelope(buffer, header) { | ||
| if (buffer.byteLength < 5 + header.length) { | ||
| return [undefined, buffer]; | ||
| } | ||
| return [ | ||
| { flags: header.flags, data: buffer.subarray(5, 5 + header.length) }, | ||
| buffer.subarray(5 + header.length), | ||
| ]; | ||
| } | ||
| // undefined: header is incomplete | ||
| function peekHeader(buffer) { | ||
| if (buffer.byteLength < 5) { | ||
| return undefined; | ||
| } | ||
| const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); | ||
| const length = view.getUint32(1); // 4 bytes message length | ||
| const flags = view.getUint8(0); // first byte is flags | ||
| return { length, flags }; | ||
| } | ||
| return function (iterable) { | ||
| return __asyncGenerator(this, arguments, function* () { | ||
| var _a, e_11, _b, _c; | ||
| let buffer = new Uint8Array(0); | ||
| const buffer = (0, envelope_js_1.createEnvelopeDecoder)(readMaxBytes); | ||
| try { | ||
@@ -612,14 +582,3 @@ for (var _d = true, iterable_11 = __asyncValues(iterable), iterable_11_1; iterable_11_1 = yield __await(iterable_11.next()), _a = iterable_11_1.done, !_a; _d = true) { | ||
| const chunk = _c; | ||
| buffer = append(buffer, chunk); | ||
| for (;;) { | ||
| const header = peekHeader(buffer); | ||
| if (!header) { | ||
| break; | ||
| } | ||
| (0, limit_io_js_1.assertReadMaxBytes)(readMaxBytes, header.length, true); | ||
| let env; | ||
| [env, buffer] = shiftEnvelope(buffer, header); | ||
| if (!env) { | ||
| break; | ||
| } | ||
| for (const env of buffer.decode(chunk)) { | ||
| yield yield __await(env); | ||
@@ -637,8 +596,3 @@ } | ||
| if (buffer.byteLength > 0) { | ||
| const header = peekHeader(buffer); | ||
| let message = "protocol error: incomplete envelope"; | ||
| if (header) { | ||
| message = `protocol error: promised ${header.length} bytes in enveloped message, got ${buffer.byteLength - 5} bytes`; | ||
| } | ||
| throw new connect_error_js_1.ConnectError(message, code_js_1.Code.InvalidArgument); | ||
| throw new connect_error_js_1.ConnectError("protocol error: incomplete envelope", code_js_1.Code.InvalidArgument); | ||
| } | ||
@@ -752,7 +706,5 @@ }); | ||
| if (it.throw !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- can't handle mutated object sensibly | ||
| w.throw = (e) => it.throw(e); | ||
| } | ||
| if (it.return !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any -- can't handle mutated object sensibly | ||
| w.return = (value) => it.return(value); | ||
@@ -927,4 +879,7 @@ } | ||
| let readResolve; | ||
| const readPromise = new Promise((resolve) => (readResolve = resolve)); | ||
| readQueue.push(readResolve); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| const readPromise = new Promise((resolve) => { | ||
| readResolve = resolve; | ||
| }); | ||
| // biome-ignore lint/style/noNonNullAssertion: initialized by promise executor | ||
| readQueue.push(readResolve); | ||
| return readPromise; | ||
@@ -966,3 +921,2 @@ }, | ||
| */ | ||
| // eslint-disable-next-line @typescript-eslint/require-await | ||
| function createAsyncIterable(items) { | ||
@@ -969,0 +923,0 @@ return __asyncGenerator(this, arguments, function* createAsyncIterable_1() { |
@@ -19,2 +19,33 @@ import type { Compression } from "./compression.js"; | ||
| /** | ||
| * Decodes chunks of raw bytes into enveloped messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| export type EnvelopeDecoder = { | ||
| /** | ||
| * Decode enveloped messages. | ||
| * | ||
| * If the chunk is incomplete, buffer for subsequent calls. | ||
| * | ||
| * If a message exceeds `readMaxBytes`, raise an error. The decoder must be | ||
| * discarded. | ||
| */ | ||
| decode(chunk: Uint8Array): EnvelopedMessage[]; | ||
| /** | ||
| * Size of the buffer. Use this property to check for incomplete data. | ||
| */ | ||
| readonly byteLength: number; | ||
| /** | ||
| * Maximum size for individual messages. | ||
| */ | ||
| readonly readMaxBytes: number; | ||
| }; | ||
| /** | ||
| * Create an EnvelopeDecoder. The `readMaxBytes` argument limits the maximum | ||
| * size for individual messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| export declare function createEnvelopeDecoder(readMaxBytes: number): EnvelopeDecoder; | ||
| /** | ||
| * Create a WHATWG ReadableStream of enveloped messages from a ReadableStream | ||
@@ -21,0 +52,0 @@ * of bytes. |
@@ -16,2 +16,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createEnvelopeDecoder = createEnvelopeDecoder; | ||
| exports.createEnvelopeReadableStream = createEnvelopeReadableStream; | ||
@@ -25,3 +26,86 @@ exports.envelopeCompress = envelopeCompress; | ||
| const compression_js_1 = require("./compression.js"); | ||
| const limit_io_js_1 = require("./limit-io.js"); | ||
| /** | ||
| * Create an EnvelopeDecoder. The `readMaxBytes` argument limits the maximum | ||
| * size for individual messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| function createEnvelopeDecoder(readMaxBytes) { | ||
| return new EnvelopeDecoderImpl(readMaxBytes); | ||
| } | ||
| class EnvelopeDecoderImpl { | ||
| constructor(readMaxBytes) { | ||
| this.readMaxBytes = readMaxBytes; | ||
| // Envelope headers are 5 bytes: 1 byte for flags, 4 bytes message length | ||
| this.header = new Uint8Array(5); | ||
| this.headerView = new DataView(this.header.buffer); | ||
| this.buf = []; | ||
| } | ||
| get byteLength() { | ||
| return this.buf.reduce((a, b) => a + b.byteLength, 0); | ||
| } | ||
| decode(chunk) { | ||
| this.buf.push(chunk); | ||
| const envs = []; | ||
| for (;;) { | ||
| let env = this.pop(); | ||
| if (!env) { | ||
| break; | ||
| } | ||
| envs.push(env); | ||
| } | ||
| return envs; | ||
| } | ||
| // consume an enveloped message | ||
| pop() { | ||
| if (!this.env) { | ||
| this.env = this.head(); | ||
| if (!this.env) { | ||
| return undefined; | ||
| } | ||
| } | ||
| if (this.cons(this.env.data)) { | ||
| const env = this.env; | ||
| this.env = undefined; | ||
| return env; | ||
| } | ||
| return undefined; | ||
| } | ||
| // consume header | ||
| head() { | ||
| if (!this.cons(this.header)) { | ||
| return undefined; | ||
| } | ||
| const flags = this.headerView.getUint8(0); // first byte is flags | ||
| const length = this.headerView.getUint32(1); // 4 bytes message length | ||
| (0, limit_io_js_1.assertReadMaxBytes)(this.readMaxBytes, length, true); | ||
| return { | ||
| flags, | ||
| data: new Uint8Array(length), | ||
| }; | ||
| } | ||
| // consume from buffer, fill target | ||
| cons(target) { | ||
| const wantLength = target.byteLength; | ||
| if (this.byteLength < wantLength) { | ||
| return false; | ||
| } | ||
| let offset = 0; | ||
| while (offset < wantLength) { | ||
| const chunk = this.buf.shift(); // we check length above | ||
| if (chunk.byteLength > wantLength - offset) { | ||
| target.set(chunk.subarray(0, wantLength - offset), offset); | ||
| this.buf.unshift(chunk.subarray(wantLength - offset)); | ||
| offset += wantLength - offset; | ||
| } | ||
| else { | ||
| target.set(chunk, offset); | ||
| offset += chunk.byteLength; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| /** | ||
| * Create a WHATWG ReadableStream of enveloped messages from a ReadableStream | ||
@@ -37,9 +121,3 @@ * of bytes. | ||
| let reader; | ||
| let buffer = new Uint8Array(0); | ||
| function append(chunk) { | ||
| const n = new Uint8Array(buffer.length + chunk.length); | ||
| n.set(buffer); | ||
| n.set(chunk, buffer.length); | ||
| buffer = n; | ||
| } | ||
| const buffer = createEnvelopeDecoder(0xffffffff); | ||
| return new ReadableStream({ | ||
@@ -50,34 +128,18 @@ start() { | ||
| async pull(controller) { | ||
| let header = undefined; | ||
| for (;;) { | ||
| if (header === undefined && buffer.byteLength >= 5) { | ||
| let length = 0; | ||
| for (let i = 1; i < 5; i++) { | ||
| length = (length << 8) + buffer[i]; | ||
| } | ||
| header = { flags: buffer[0], length }; | ||
| } | ||
| if (header !== undefined && buffer.byteLength >= header.length + 5) { | ||
| break; | ||
| } | ||
| let enqueuedOnce = false; | ||
| while (!enqueuedOnce) { | ||
| const result = await reader.read(); | ||
| if (result.done) { | ||
| break; | ||
| } | ||
| append(result.value); | ||
| } | ||
| if (header === undefined) { | ||
| if (buffer.byteLength == 0) { | ||
| if (buffer.byteLength > 0) { | ||
| controller.error(new connect_error_js_1.ConnectError("protocol error: incomplete envelope", code_js_1.Code.InvalidArgument)); | ||
| } | ||
| controller.close(); | ||
| return; | ||
| } | ||
| controller.error(new connect_error_js_1.ConnectError("premature end of stream", code_js_1.Code.DataLoss)); | ||
| return; | ||
| else { | ||
| for (const env of buffer.decode(result.value)) { | ||
| controller.enqueue(env); | ||
| enqueuedOnce = true; | ||
| } | ||
| } | ||
| } | ||
| const data = buffer.subarray(5, 5 + header.length); | ||
| buffer = buffer.subarray(5 + header.length); | ||
| controller.enqueue({ | ||
| flags: header.flags, | ||
| data, | ||
| }); | ||
| }, | ||
@@ -84,0 +146,0 @@ }); |
@@ -47,6 +47,6 @@ "use strict"; | ||
| if (it.throw !== undefined) { | ||
| res.throw = (e) => it.throw(e).then(transform); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| res.throw = (e) => it.throw(e).then(transform); | ||
| } | ||
| if (it.return !== undefined) { | ||
| res.return = (v) => it.return(v).then(transform); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| res.return = (v) => it.return(v).then(transform); | ||
| } | ||
@@ -53,0 +53,0 @@ return res; |
@@ -58,7 +58,5 @@ "use strict"; | ||
| if (it.throw !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- can't handle mutated object sensibly | ||
| w.throw = (e) => it.throw(e); | ||
| } | ||
| if (it.return !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any -- can't handle mutated object sensibly | ||
| w.return = (value) => it.return(value); | ||
@@ -65,0 +63,0 @@ } |
@@ -43,3 +43,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| function createUnaryFn(transport, method) { | ||
| return function (requestMessage, callback, options) { | ||
| return (requestMessage, callback, options) => { | ||
| const abort = new AbortController(); | ||
@@ -66,3 +66,3 @@ options = wrapSignal(abort, options); | ||
| function createServerStreamingFn(transport, method) { | ||
| return function (input, onResponse, onClose, options) { | ||
| return (input, onResponse, onClose, options) => { | ||
| const abort = new AbortController(); | ||
@@ -69,0 +69,0 @@ async function run() { |
@@ -59,4 +59,4 @@ import { Code } from "./code.js"; | ||
| * - If the value is already a ConnectError, return it as is. | ||
| * - If the value is an AbortError from the fetch API, return the message | ||
| * of the AbortError with code Canceled. | ||
| * - If the value is an AbortError or TimeoutError from the fetch API, return | ||
| * the message of the error with code Canceled. | ||
| * - For other Errors, return the error message with code Unknown by default. | ||
@@ -63,0 +63,0 @@ * - For other values, return the values String representation as a message, |
@@ -53,4 +53,4 @@ // Copyright 2021-2025 The Connect Authors | ||
| * - If the value is already a ConnectError, return it as is. | ||
| * - If the value is an AbortError from the fetch API, return the message | ||
| * of the AbortError with code Canceled. | ||
| * - If the value is an AbortError or TimeoutError from the fetch API, return | ||
| * the message of the error with code Canceled. | ||
| * - For other Errors, return the error message with code Unknown by default. | ||
@@ -67,6 +67,5 @@ * - For other values, return the values String representation as a message, | ||
| if (reason instanceof Error) { | ||
| if (reason.name == "AbortError") { | ||
| // Fetch requests can only be canceled with an AbortController. | ||
| // We detect that condition by looking at the name of the raised | ||
| // error object, and translate to the appropriate status code. | ||
| if (reason.name == "AbortError" || reason.name == "TimeoutError") { | ||
| // Fetch requests can only be canceled with an AbortController, | ||
| // or with AbortSignal.timeout(). | ||
| return new ConnectError(reason.message, Code.Canceled); | ||
@@ -73,0 +72,0 @@ } |
@@ -20,6 +20,9 @@ // Copyright 2021-2025 The Connect Authors | ||
| export function applyInterceptors(next, interceptors) { | ||
| var _a; | ||
| return ((_a = interceptors === null || interceptors === void 0 ? void 0 : interceptors.concat().reverse().reduce( | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-argument | ||
| (n, i) => i(n), next)) !== null && _a !== void 0 ? _a : next); | ||
| if (!interceptors) { | ||
| return next; | ||
| } | ||
| for (const i of interceptors.concat().reverse()) { | ||
| next = i(next); | ||
| } | ||
| return next; | ||
| } |
@@ -64,3 +64,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| export function createUnaryFn(transport, method) { | ||
| return async function (input, options) { | ||
| return async (input, options) => { | ||
| var _a, _b; | ||
@@ -74,8 +74,6 @@ const response = await transport.unary(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, input, options === null || options === void 0 ? void 0 : options.contextValues); | ||
| export function createServerStreamingFn(transport, method) { | ||
| return function (input, options) { | ||
| return handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, createAsyncIterable([input]), options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| }; | ||
| return (input, options) => handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, createAsyncIterable([input]), options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| } | ||
| export function createClientStreamingFn(transport, method) { | ||
| return async function (request, options) { | ||
| return async (request, options) => { | ||
| var _a, e_1, _b, _c; | ||
@@ -114,5 +112,3 @@ var _d, _e; | ||
| export function createBiDiStreamingFn(transport, method) { | ||
| return function (request, options) { | ||
| return handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, request, options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| }; | ||
| return (request, options) => handleStreamResponse(transport.stream(method, options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.timeoutMs, options === null || options === void 0 ? void 0 : options.headers, request, options === null || options === void 0 ? void 0 : options.contextValues), options); | ||
| } | ||
@@ -119,0 +115,0 @@ function handleStreamResponse(stream, options) { |
@@ -22,5 +22,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| } | ||
| else { | ||
| return encodeURIComponent(new TextDecoder().decode(message)); | ||
| } | ||
| return encodeURIComponent(new TextDecoder().decode(message)); | ||
| } | ||
@@ -49,5 +47,5 @@ /** | ||
| const url = request.url + query; | ||
| const header = new Headers(request.header); | ||
| // Omit headers that are not used for unary GET requests. | ||
| const header = new Headers(request.header); | ||
| [ | ||
| for (const h of [ | ||
| headerProtocolVersion, | ||
@@ -58,5 +56,7 @@ headerContentType, | ||
| headerUnaryAcceptEncoding, | ||
| ].forEach((h) => header.delete(h)); | ||
| ]) { | ||
| header.delete(h); | ||
| } | ||
| return Object.assign(Object.assign({}, request), { requestMethod: "GET", url, | ||
| header }); | ||
| } |
@@ -39,3 +39,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| result.set(headerUserAgent, "connect-es/2.0.2"); | ||
| result.set(headerUserAgent, "connect-es/2.0.3"); | ||
| } | ||
@@ -42,0 +42,0 @@ return result; |
@@ -35,3 +35,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| } | ||
| else if (v !== protocolVersion) { | ||
| if (v !== protocolVersion) { | ||
| throw new ConnectError(`${headerProtocolVersion} must be "${protocolVersion}": got "${v}"`, Code.InvalidArgument); | ||
@@ -51,5 +51,5 @@ } | ||
| } | ||
| else if (v !== `v${protocolVersion}`) { | ||
| if (v !== `v${protocolVersion}`) { | ||
| throw new ConnectError(`${paramConnectVersion} must be "v${protocolVersion}": got "${v}"`, Code.InvalidArgument); | ||
| } | ||
| } |
@@ -22,2 +22,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| export function requestHeader(useBinaryFormat, timeoutMs, userProvidedHeaders, setUserAgent) { | ||
| var _a, _b; | ||
| const result = new Headers(userProvidedHeaders !== null && userProvidedHeaders !== void 0 ? userProvidedHeaders : {}); | ||
@@ -31,8 +32,3 @@ // Note that we do not support the grpc-web-text format. | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| let userAgent = "connect-es/2.0.2"; | ||
| userAgent = result.has(headerUserAgent) | ||
| ? result.get(headerUserAgent) | ||
| : result.has(headerXUserAgent) | ||
| ? result.get(headerXUserAgent) | ||
| : userAgent; | ||
| const userAgent = (_b = (_a = result.get(headerUserAgent)) !== null && _a !== void 0 ? _a : result.get(headerXUserAgent)) !== null && _b !== void 0 ? _b : "connect-es/2.0.3"; | ||
| result.set(headerXUserAgent, userAgent); | ||
@@ -39,0 +35,0 @@ if (setUserAgent) { |
@@ -1,2 +0,2 @@ | ||
| import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; | ||
| import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; | ||
| import type { Any } from "@bufbuild/protobuf/wkt"; | ||
@@ -3,0 +3,0 @@ import type { Message } from "@bufbuild/protobuf"; |
@@ -14,3 +14,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| // limitations under the License. | ||
| import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; | ||
| import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; | ||
| import { file_google_protobuf_any } from "@bufbuild/protobuf/wkt"; | ||
@@ -17,0 +17,0 @@ /** |
@@ -28,3 +28,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| // See https://github.com/grpc/grpc/blob/c462bb8d485fc1434ecfae438823ca8d14cf3154/doc/PROTOCOL-HTTP2.md#user-agents | ||
| result.set(headerUserAgent, "connect-es/2.0.2"); | ||
| result.set(headerUserAgent, "connect-es/2.0.3"); | ||
| } | ||
@@ -31,0 +31,0 @@ if (timeoutMs !== undefined) { |
@@ -1,2 +0,2 @@ | ||
| import type { EnvelopedMessage } from "./envelope.js"; | ||
| import { type EnvelopedMessage } from "./envelope.js"; | ||
| import type { Serialization } from "./serialization.js"; | ||
@@ -3,0 +3,0 @@ import type { Compression } from "./compression.js"; |
@@ -41,2 +41,3 @@ // Copyright 2021-2025 The Connect Authors | ||
| import { ConnectError } from "../connect-error.js"; | ||
| import { createEnvelopeDecoder } from "./envelope.js"; | ||
| import { encodeEnvelope, envelopeCompress, envelopeDecompress, } from "./envelope.js"; | ||
@@ -51,3 +52,2 @@ import { assertReadMaxBytes } from "./limit-io.js"; | ||
| } | ||
| // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
| // @ts-ignore | ||
@@ -77,3 +77,3 @@ iterable = pipe(iterable, ...transforms, { propagateDownStreamError: false }); | ||
| export function sinkAll() { | ||
| return async function (iterable) { | ||
| return async (iterable) => { | ||
| var _a, e_1, _b, _c; | ||
@@ -114,5 +114,3 @@ const all = []; | ||
| export function sinkAllBytes(readMaxBytes, lengthHint) { | ||
| return async function (iterable) { | ||
| return await readAllBytes(iterable, readMaxBytes, lengthHint); | ||
| }; | ||
| return async (iterable) => await readAllBytes(iterable, readMaxBytes, lengthHint); | ||
| } | ||
@@ -549,34 +547,6 @@ export function pipe(source, ...rest) { | ||
| export function transformSplitEnvelope(readMaxBytes) { | ||
| // append chunk to buffer, returning updated buffer | ||
| function append(buffer, chunk) { | ||
| const n = new Uint8Array(buffer.byteLength + chunk.byteLength); | ||
| n.set(buffer); | ||
| n.set(chunk, buffer.length); | ||
| return n; | ||
| } | ||
| // tuple 0: envelope, or undefined if incomplete | ||
| // tuple 1: remainder of the buffer | ||
| function shiftEnvelope(buffer, header) { | ||
| if (buffer.byteLength < 5 + header.length) { | ||
| return [undefined, buffer]; | ||
| } | ||
| return [ | ||
| { flags: header.flags, data: buffer.subarray(5, 5 + header.length) }, | ||
| buffer.subarray(5 + header.length), | ||
| ]; | ||
| } | ||
| // undefined: header is incomplete | ||
| function peekHeader(buffer) { | ||
| if (buffer.byteLength < 5) { | ||
| return undefined; | ||
| } | ||
| const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); | ||
| const length = view.getUint32(1); // 4 bytes message length | ||
| const flags = view.getUint8(0); // first byte is flags | ||
| return { length, flags }; | ||
| } | ||
| return function (iterable) { | ||
| return __asyncGenerator(this, arguments, function* () { | ||
| var _a, e_11, _b, _c; | ||
| let buffer = new Uint8Array(0); | ||
| const buffer = createEnvelopeDecoder(readMaxBytes); | ||
| try { | ||
@@ -587,14 +557,3 @@ for (var _d = true, iterable_11 = __asyncValues(iterable), iterable_11_1; iterable_11_1 = yield __await(iterable_11.next()), _a = iterable_11_1.done, !_a; _d = true) { | ||
| const chunk = _c; | ||
| buffer = append(buffer, chunk); | ||
| for (;;) { | ||
| const header = peekHeader(buffer); | ||
| if (!header) { | ||
| break; | ||
| } | ||
| assertReadMaxBytes(readMaxBytes, header.length, true); | ||
| let env; | ||
| [env, buffer] = shiftEnvelope(buffer, header); | ||
| if (!env) { | ||
| break; | ||
| } | ||
| for (const env of buffer.decode(chunk)) { | ||
| yield yield __await(env); | ||
@@ -612,8 +571,3 @@ } | ||
| if (buffer.byteLength > 0) { | ||
| const header = peekHeader(buffer); | ||
| let message = "protocol error: incomplete envelope"; | ||
| if (header) { | ||
| message = `protocol error: promised ${header.length} bytes in enveloped message, got ${buffer.byteLength - 5} bytes`; | ||
| } | ||
| throw new ConnectError(message, Code.InvalidArgument); | ||
| throw new ConnectError("protocol error: incomplete envelope", Code.InvalidArgument); | ||
| } | ||
@@ -727,7 +681,5 @@ }); | ||
| if (it.throw !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- can't handle mutated object sensibly | ||
| w.throw = (e) => it.throw(e); | ||
| } | ||
| if (it.return !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any -- can't handle mutated object sensibly | ||
| w.return = (value) => it.return(value); | ||
@@ -902,4 +854,7 @@ } | ||
| let readResolve; | ||
| const readPromise = new Promise((resolve) => (readResolve = resolve)); | ||
| readQueue.push(readResolve); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| const readPromise = new Promise((resolve) => { | ||
| readResolve = resolve; | ||
| }); | ||
| // biome-ignore lint/style/noNonNullAssertion: initialized by promise executor | ||
| readQueue.push(readResolve); | ||
| return readPromise; | ||
@@ -941,3 +896,2 @@ }, | ||
| */ | ||
| // eslint-disable-next-line @typescript-eslint/require-await | ||
| export function createAsyncIterable(items) { | ||
@@ -944,0 +898,0 @@ return __asyncGenerator(this, arguments, function* createAsyncIterable_1() { |
@@ -19,2 +19,33 @@ import type { Compression } from "./compression.js"; | ||
| /** | ||
| * Decodes chunks of raw bytes into enveloped messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| export type EnvelopeDecoder = { | ||
| /** | ||
| * Decode enveloped messages. | ||
| * | ||
| * If the chunk is incomplete, buffer for subsequent calls. | ||
| * | ||
| * If a message exceeds `readMaxBytes`, raise an error. The decoder must be | ||
| * discarded. | ||
| */ | ||
| decode(chunk: Uint8Array): EnvelopedMessage[]; | ||
| /** | ||
| * Size of the buffer. Use this property to check for incomplete data. | ||
| */ | ||
| readonly byteLength: number; | ||
| /** | ||
| * Maximum size for individual messages. | ||
| */ | ||
| readonly readMaxBytes: number; | ||
| }; | ||
| /** | ||
| * Create an EnvelopeDecoder. The `readMaxBytes` argument limits the maximum | ||
| * size for individual messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| export declare function createEnvelopeDecoder(readMaxBytes: number): EnvelopeDecoder; | ||
| /** | ||
| * Create a WHATWG ReadableStream of enveloped messages from a ReadableStream | ||
@@ -21,0 +52,0 @@ * of bytes. |
@@ -17,3 +17,86 @@ // Copyright 2021-2025 The Connect Authors | ||
| import { compressedFlag } from "./compression.js"; | ||
| import { assertReadMaxBytes } from "./limit-io.js"; | ||
| /** | ||
| * Create an EnvelopeDecoder. The `readMaxBytes` argument limits the maximum | ||
| * size for individual messages. | ||
| * | ||
| * @private Internal code, does not follow semantic versioning. | ||
| */ | ||
| export function createEnvelopeDecoder(readMaxBytes) { | ||
| return new EnvelopeDecoderImpl(readMaxBytes); | ||
| } | ||
| class EnvelopeDecoderImpl { | ||
| constructor(readMaxBytes) { | ||
| this.readMaxBytes = readMaxBytes; | ||
| // Envelope headers are 5 bytes: 1 byte for flags, 4 bytes message length | ||
| this.header = new Uint8Array(5); | ||
| this.headerView = new DataView(this.header.buffer); | ||
| this.buf = []; | ||
| } | ||
| get byteLength() { | ||
| return this.buf.reduce((a, b) => a + b.byteLength, 0); | ||
| } | ||
| decode(chunk) { | ||
| this.buf.push(chunk); | ||
| const envs = []; | ||
| for (;;) { | ||
| let env = this.pop(); | ||
| if (!env) { | ||
| break; | ||
| } | ||
| envs.push(env); | ||
| } | ||
| return envs; | ||
| } | ||
| // consume an enveloped message | ||
| pop() { | ||
| if (!this.env) { | ||
| this.env = this.head(); | ||
| if (!this.env) { | ||
| return undefined; | ||
| } | ||
| } | ||
| if (this.cons(this.env.data)) { | ||
| const env = this.env; | ||
| this.env = undefined; | ||
| return env; | ||
| } | ||
| return undefined; | ||
| } | ||
| // consume header | ||
| head() { | ||
| if (!this.cons(this.header)) { | ||
| return undefined; | ||
| } | ||
| const flags = this.headerView.getUint8(0); // first byte is flags | ||
| const length = this.headerView.getUint32(1); // 4 bytes message length | ||
| assertReadMaxBytes(this.readMaxBytes, length, true); | ||
| return { | ||
| flags, | ||
| data: new Uint8Array(length), | ||
| }; | ||
| } | ||
| // consume from buffer, fill target | ||
| cons(target) { | ||
| const wantLength = target.byteLength; | ||
| if (this.byteLength < wantLength) { | ||
| return false; | ||
| } | ||
| let offset = 0; | ||
| while (offset < wantLength) { | ||
| const chunk = this.buf.shift(); // we check length above | ||
| if (chunk.byteLength > wantLength - offset) { | ||
| target.set(chunk.subarray(0, wantLength - offset), offset); | ||
| this.buf.unshift(chunk.subarray(wantLength - offset)); | ||
| offset += wantLength - offset; | ||
| } | ||
| else { | ||
| target.set(chunk, offset); | ||
| offset += chunk.byteLength; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| /** | ||
| * Create a WHATWG ReadableStream of enveloped messages from a ReadableStream | ||
@@ -29,9 +112,3 @@ * of bytes. | ||
| let reader; | ||
| let buffer = new Uint8Array(0); | ||
| function append(chunk) { | ||
| const n = new Uint8Array(buffer.length + chunk.length); | ||
| n.set(buffer); | ||
| n.set(chunk, buffer.length); | ||
| buffer = n; | ||
| } | ||
| const buffer = createEnvelopeDecoder(0xffffffff); | ||
| return new ReadableStream({ | ||
@@ -42,34 +119,18 @@ start() { | ||
| async pull(controller) { | ||
| let header = undefined; | ||
| for (;;) { | ||
| if (header === undefined && buffer.byteLength >= 5) { | ||
| let length = 0; | ||
| for (let i = 1; i < 5; i++) { | ||
| length = (length << 8) + buffer[i]; | ||
| } | ||
| header = { flags: buffer[0], length }; | ||
| } | ||
| if (header !== undefined && buffer.byteLength >= header.length + 5) { | ||
| break; | ||
| } | ||
| let enqueuedOnce = false; | ||
| while (!enqueuedOnce) { | ||
| const result = await reader.read(); | ||
| if (result.done) { | ||
| break; | ||
| } | ||
| append(result.value); | ||
| } | ||
| if (header === undefined) { | ||
| if (buffer.byteLength == 0) { | ||
| if (buffer.byteLength > 0) { | ||
| controller.error(new ConnectError("protocol error: incomplete envelope", Code.InvalidArgument)); | ||
| } | ||
| controller.close(); | ||
| return; | ||
| } | ||
| controller.error(new ConnectError("premature end of stream", Code.DataLoss)); | ||
| return; | ||
| else { | ||
| for (const env of buffer.decode(result.value)) { | ||
| controller.enqueue(env); | ||
| enqueuedOnce = true; | ||
| } | ||
| } | ||
| } | ||
| const data = buffer.subarray(5, 5 + header.length); | ||
| buffer = buffer.subarray(5 + header.length); | ||
| controller.enqueue({ | ||
| flags: header.flags, | ||
| data, | ||
| }); | ||
| }, | ||
@@ -76,0 +137,0 @@ }); |
@@ -43,6 +43,6 @@ // Copyright 2021-2025 The Connect Authors | ||
| if (it.throw !== undefined) { | ||
| res.throw = (e) => it.throw(e).then(transform); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| res.throw = (e) => it.throw(e).then(transform); | ||
| } | ||
| if (it.return !== undefined) { | ||
| res.return = (v) => it.return(v).then(transform); // eslint-disable-line @typescript-eslint/no-non-null-assertion | ||
| res.return = (v) => it.return(v).then(transform); | ||
| } | ||
@@ -49,0 +49,0 @@ return res; |
@@ -55,7 +55,5 @@ // Copyright 2021-2025 The Connect Authors | ||
| if (it.throw !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- can't handle mutated object sensibly | ||
| w.throw = (e) => it.throw(e); | ||
| } | ||
| if (it.return !== undefined) { | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any -- can't handle mutated object sensibly | ||
| w.return = (value) => it.return(value); | ||
@@ -62,0 +60,0 @@ } |
+11
-19
| { | ||
| "name": "@connectrpc/connect", | ||
| "version": "2.0.2", | ||
| "version": "2.0.3", | ||
| "description": "Type-safe APIs with Protobuf and TypeScript.", | ||
@@ -20,5 +20,5 @@ "license": "Apache-2.0", | ||
| "test": "jasmine --config=jasmine.json", | ||
| "format": "prettier --write --ignore-unknown '.' '!dist' '!src/protocol-grpc/gen'", | ||
| "format": "biome format --write", | ||
| "license-header": "license-header", | ||
| "lint": "eslint --max-warnings 0 .", | ||
| "lint": "biome lint --error-on-warnings", | ||
| "attw": "attw --pack" | ||
@@ -53,14 +53,6 @@ }, | ||
| "*": { | ||
| "protocol": [ | ||
| "./dist/cjs/protocol/index.d.ts" | ||
| ], | ||
| "protocol-connect": [ | ||
| "./dist/cjs/protocol-connect/index.d.ts" | ||
| ], | ||
| "protocol-grpc": [ | ||
| "./dist/cjs/protocol-grpc/index.d.ts" | ||
| ], | ||
| "protocol-grpc-web": [ | ||
| "./dist/cjs/protocol-grpc-web/index.d.ts" | ||
| ] | ||
| "protocol": ["./dist/cjs/protocol/index.d.ts"], | ||
| "protocol-connect": ["./dist/cjs/protocol-connect/index.d.ts"], | ||
| "protocol-grpc": ["./dist/cjs/protocol-grpc/index.d.ts"], | ||
| "protocol-grpc-web": ["./dist/cjs/protocol-grpc-web/index.d.ts"] | ||
| } | ||
@@ -72,7 +64,7 @@ }, | ||
| "devDependencies": { | ||
| "@bufbuild/buf": "^1.50.0", | ||
| "@bufbuild/protoc-gen-es": "^2.2.3", | ||
| "@types/jasmine": "^5.1.5", | ||
| "jasmine": "^5.5.0" | ||
| "@bufbuild/buf": "^1.55.1", | ||
| "@bufbuild/protoc-gen-es": "^2.6.0", | ||
| "@types/jasmine": "^5.1.8", | ||
| "jasmine": "^5.8.0" | ||
| } | ||
| } |
+1
-1
@@ -9,3 +9,3 @@ # @connectrpc/connect | ||
| ``` | ||
| ```proto | ||
| service ElizaService { | ||
@@ -12,0 +12,0 @@ rpc Say(SayRequest) returns (SayResponse) {} |
18611
0.42%856873
-0.03%