initial commit of actions

This commit is contained in:
Dominik Polakovics Polakovics 2026-01-31 18:56:04 +01:00
commit 949ece5785
44660 changed files with 12034344 additions and 0 deletions

View file

@ -0,0 +1,50 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientStreamingCall = void 0;
/**
* A client streaming RPC call. This means that the clients sends 0, 1, or
* more messages to the server, and the server replies with exactly one
* message.
*/
class ClientStreamingCall {
constructor(method, requestHeaders, request, headers, response, status, trailers) {
this.method = method;
this.requestHeaders = requestHeaders;
this.requests = request;
this.headers = headers;
this.response = response;
this.status = status;
this.trailers = trailers;
}
/**
* Instead of awaiting the response status and trailers, you can
* just as well await this call itself to receive the server outcome.
* Note that it may still be valid to send more request messages.
*/
then(onfulfilled, onrejected) {
return this.promiseFinished().then(value => onfulfilled ? Promise.resolve(onfulfilled(value)) : value, reason => onrejected ? Promise.resolve(onrejected(reason)) : Promise.reject(reason));
}
promiseFinished() {
return __awaiter(this, void 0, void 0, function* () {
let [headers, response, status, trailers] = yield Promise.all([this.headers, this.response, this.status, this.trailers]);
return {
method: this.method,
requestHeaders: this.requestHeaders,
headers,
response,
status,
trailers
};
});
}
}
exports.ClientStreamingCall = ClientStreamingCall;

View file

@ -0,0 +1,86 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Deferred = exports.DeferredState = void 0;
var DeferredState;
(function (DeferredState) {
DeferredState[DeferredState["PENDING"] = 0] = "PENDING";
DeferredState[DeferredState["REJECTED"] = 1] = "REJECTED";
DeferredState[DeferredState["RESOLVED"] = 2] = "RESOLVED";
})(DeferredState = exports.DeferredState || (exports.DeferredState = {}));
/**
* A deferred promise. This is a "controller" for a promise, which lets you
* pass a promise around and reject or resolve it from the outside.
*
* Warning: This class is to be used with care. Using it can make code very
* difficult to read. It is intended for use in library code that exposes
* promises, not for regular business logic.
*/
class Deferred {
/**
* @param preventUnhandledRejectionWarning - prevents the warning
* "Unhandled Promise rejection" by adding a noop rejection handler.
* Working with calls returned from the runtime-rpc package in an
* async function usually means awaiting one call property after
* the other. This means that the "status" is not being awaited when
* an earlier await for the "headers" is rejected. This causes the
* "unhandled promise reject" warning. A more correct behaviour for
* calls might be to become aware whether at least one of the
* promises is handled and swallow the rejection warning for the
* others.
*/
constructor(preventUnhandledRejectionWarning = true) {
this._state = DeferredState.PENDING;
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
if (preventUnhandledRejectionWarning) {
this._promise.catch(_ => { });
}
}
/**
* Get the current state of the promise.
*/
get state() {
return this._state;
}
/**
* Get the deferred promise.
*/
get promise() {
return this._promise;
}
/**
* Resolve the promise. Throws if the promise is already resolved or rejected.
*/
resolve(value) {
if (this.state !== DeferredState.PENDING)
throw new Error(`cannot resolve ${DeferredState[this.state].toLowerCase()}`);
this._resolve(value);
this._state = DeferredState.RESOLVED;
}
/**
* Reject the promise. Throws if the promise is already resolved or rejected.
*/
reject(reason) {
if (this.state !== DeferredState.PENDING)
throw new Error(`cannot reject ${DeferredState[this.state].toLowerCase()}`);
this._reject(reason);
this._state = DeferredState.REJECTED;
}
/**
* Resolve the promise. Ignore if not pending.
*/
resolvePending(val) {
if (this._state === DeferredState.PENDING)
this.resolve(val);
}
/**
* Reject the promise. Ignore if not pending.
*/
rejectPending(reason) {
if (this._state === DeferredState.PENDING)
this.reject(reason);
}
}
exports.Deferred = Deferred;

View file

@ -0,0 +1,49 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DuplexStreamingCall = void 0;
/**
* A duplex streaming RPC call. This means that the clients sends an
* arbitrary amount of messages to the server, while at the same time,
* the server sends an arbitrary amount of messages to the client.
*/
class DuplexStreamingCall {
constructor(method, requestHeaders, request, headers, response, status, trailers) {
this.method = method;
this.requestHeaders = requestHeaders;
this.requests = request;
this.headers = headers;
this.responses = response;
this.status = status;
this.trailers = trailers;
}
/**
* Instead of awaiting the response status and trailers, you can
* just as well await this call itself to receive the server outcome.
* Note that it may still be valid to send more request messages.
*/
then(onfulfilled, onrejected) {
return this.promiseFinished().then(value => onfulfilled ? Promise.resolve(onfulfilled(value)) : value, reason => onrejected ? Promise.resolve(onrejected(reason)) : Promise.reject(reason));
}
promiseFinished() {
return __awaiter(this, void 0, void 0, function* () {
let [headers, status, trailers] = yield Promise.all([this.headers, this.status, this.trailers]);
return {
method: this.method,
requestHeaders: this.requestHeaders,
headers,
status,
trailers,
};
});
}
}
exports.DuplexStreamingCall = DuplexStreamingCall;

View file

@ -0,0 +1,38 @@
"use strict";
// Public API of the rpc runtime.
// Note: we do not use `export * from ...` to help tree shakers,
// webpack verbose output hints that this should be useful
Object.defineProperty(exports, "__esModule", { value: true });
var service_type_1 = require("./service-type");
Object.defineProperty(exports, "ServiceType", { enumerable: true, get: function () { return service_type_1.ServiceType; } });
var reflection_info_1 = require("./reflection-info");
Object.defineProperty(exports, "readMethodOptions", { enumerable: true, get: function () { return reflection_info_1.readMethodOptions; } });
Object.defineProperty(exports, "readMethodOption", { enumerable: true, get: function () { return reflection_info_1.readMethodOption; } });
Object.defineProperty(exports, "readServiceOption", { enumerable: true, get: function () { return reflection_info_1.readServiceOption; } });
var rpc_error_1 = require("./rpc-error");
Object.defineProperty(exports, "RpcError", { enumerable: true, get: function () { return rpc_error_1.RpcError; } });
var rpc_options_1 = require("./rpc-options");
Object.defineProperty(exports, "mergeRpcOptions", { enumerable: true, get: function () { return rpc_options_1.mergeRpcOptions; } });
var rpc_output_stream_1 = require("./rpc-output-stream");
Object.defineProperty(exports, "RpcOutputStreamController", { enumerable: true, get: function () { return rpc_output_stream_1.RpcOutputStreamController; } });
var test_transport_1 = require("./test-transport");
Object.defineProperty(exports, "TestTransport", { enumerable: true, get: function () { return test_transport_1.TestTransport; } });
var deferred_1 = require("./deferred");
Object.defineProperty(exports, "Deferred", { enumerable: true, get: function () { return deferred_1.Deferred; } });
Object.defineProperty(exports, "DeferredState", { enumerable: true, get: function () { return deferred_1.DeferredState; } });
var duplex_streaming_call_1 = require("./duplex-streaming-call");
Object.defineProperty(exports, "DuplexStreamingCall", { enumerable: true, get: function () { return duplex_streaming_call_1.DuplexStreamingCall; } });
var client_streaming_call_1 = require("./client-streaming-call");
Object.defineProperty(exports, "ClientStreamingCall", { enumerable: true, get: function () { return client_streaming_call_1.ClientStreamingCall; } });
var server_streaming_call_1 = require("./server-streaming-call");
Object.defineProperty(exports, "ServerStreamingCall", { enumerable: true, get: function () { return server_streaming_call_1.ServerStreamingCall; } });
var unary_call_1 = require("./unary-call");
Object.defineProperty(exports, "UnaryCall", { enumerable: true, get: function () { return unary_call_1.UnaryCall; } });
var rpc_interceptor_1 = require("./rpc-interceptor");
Object.defineProperty(exports, "stackIntercept", { enumerable: true, get: function () { return rpc_interceptor_1.stackIntercept; } });
Object.defineProperty(exports, "stackDuplexStreamingInterceptors", { enumerable: true, get: function () { return rpc_interceptor_1.stackDuplexStreamingInterceptors; } });
Object.defineProperty(exports, "stackClientStreamingInterceptors", { enumerable: true, get: function () { return rpc_interceptor_1.stackClientStreamingInterceptors; } });
Object.defineProperty(exports, "stackServerStreamingInterceptors", { enumerable: true, get: function () { return rpc_interceptor_1.stackServerStreamingInterceptors; } });
Object.defineProperty(exports, "stackUnaryInterceptors", { enumerable: true, get: function () { return rpc_interceptor_1.stackUnaryInterceptors; } });
var server_call_context_1 = require("./server-call-context");
Object.defineProperty(exports, "ServerCallContextController", { enumerable: true, get: function () { return server_call_context_1.ServerCallContextController; } });

View file

@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readServiceOption = exports.readMethodOption = exports.readMethodOptions = exports.normalizeMethodInfo = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
/**
* Turns PartialMethodInfo into MethodInfo.
*/
function normalizeMethodInfo(method, service) {
var _a, _b, _c;
let m = method;
m.service = service;
m.localName = (_a = m.localName) !== null && _a !== void 0 ? _a : runtime_1.lowerCamelCase(m.name);
// noinspection PointlessBooleanExpressionJS
m.serverStreaming = !!m.serverStreaming;
// noinspection PointlessBooleanExpressionJS
m.clientStreaming = !!m.clientStreaming;
m.options = (_b = m.options) !== null && _b !== void 0 ? _b : {};
m.idempotency = (_c = m.idempotency) !== null && _c !== void 0 ? _c : undefined;
return m;
}
exports.normalizeMethodInfo = normalizeMethodInfo;
/**
* Read custom method options from a generated service client.
*
* @deprecated use readMethodOption()
*/
function readMethodOptions(service, methodName, extensionName, extensionType) {
var _a;
const options = (_a = service.methods.find((m, i) => m.localName === methodName || i === methodName)) === null || _a === void 0 ? void 0 : _a.options;
return options && options[extensionName] ? extensionType.fromJson(options[extensionName]) : undefined;
}
exports.readMethodOptions = readMethodOptions;
function readMethodOption(service, methodName, extensionName, extensionType) {
var _a;
const options = (_a = service.methods.find((m, i) => m.localName === methodName || i === methodName)) === null || _a === void 0 ? void 0 : _a.options;
if (!options) {
return undefined;
}
const optionVal = options[extensionName];
if (optionVal === undefined) {
return optionVal;
}
return extensionType ? extensionType.fromJson(optionVal) : optionVal;
}
exports.readMethodOption = readMethodOption;
function readServiceOption(service, extensionName, extensionType) {
const options = service.options;
if (!options) {
return undefined;
}
const optionVal = options[extensionName];
if (optionVal === undefined) {
return optionVal;
}
return extensionType ? extensionType.fromJson(optionVal) : optionVal;
}
exports.readServiceOption = readServiceOption;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcError = void 0;
/**
* An error that occurred while calling a RPC method.
*/
class RpcError extends Error {
constructor(message, code = 'UNKNOWN', meta) {
super(message);
this.name = 'RpcError';
// see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#example
Object.setPrototypeOf(this, new.target.prototype);
this.code = code;
this.meta = meta !== null && meta !== void 0 ? meta : {};
}
toString() {
const l = [this.name + ': ' + this.message];
if (this.code) {
l.push('');
l.push('Code: ' + this.code);
}
if (this.serviceName && this.methodName) {
l.push('Method: ' + this.serviceName + '/' + this.methodName);
}
let m = Object.entries(this.meta);
if (m.length) {
l.push('');
l.push('Meta:');
for (let [k, v] of m) {
l.push(` ${k}: ${v}`);
}
}
return l.join('\n');
}
}
exports.RpcError = RpcError;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.stackDuplexStreamingInterceptors = exports.stackClientStreamingInterceptors = exports.stackServerStreamingInterceptors = exports.stackUnaryInterceptors = exports.stackIntercept = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
/**
* Creates a "stack" of of all interceptors specified in the given `RpcOptions`.
* Used by generated client implementations.
* @internal
*/
function stackIntercept(kind, transport, method, options, input) {
var _a, _b, _c, _d;
if (kind == "unary") {
let tail = (mtd, inp, opt) => transport.unary(mtd, inp, opt);
for (const curr of ((_a = options.interceptors) !== null && _a !== void 0 ? _a : []).filter(i => i.interceptUnary).reverse()) {
const next = tail;
tail = (mtd, inp, opt) => curr.interceptUnary(next, mtd, inp, opt);
}
return tail(method, input, options);
}
if (kind == "serverStreaming") {
let tail = (mtd, inp, opt) => transport.serverStreaming(mtd, inp, opt);
for (const curr of ((_b = options.interceptors) !== null && _b !== void 0 ? _b : []).filter(i => i.interceptServerStreaming).reverse()) {
const next = tail;
tail = (mtd, inp, opt) => curr.interceptServerStreaming(next, mtd, inp, opt);
}
return tail(method, input, options);
}
if (kind == "clientStreaming") {
let tail = (mtd, opt) => transport.clientStreaming(mtd, opt);
for (const curr of ((_c = options.interceptors) !== null && _c !== void 0 ? _c : []).filter(i => i.interceptClientStreaming).reverse()) {
const next = tail;
tail = (mtd, opt) => curr.interceptClientStreaming(next, mtd, opt);
}
return tail(method, options);
}
if (kind == "duplex") {
let tail = (mtd, opt) => transport.duplex(mtd, opt);
for (const curr of ((_d = options.interceptors) !== null && _d !== void 0 ? _d : []).filter(i => i.interceptDuplex).reverse()) {
const next = tail;
tail = (mtd, opt) => curr.interceptDuplex(next, mtd, opt);
}
return tail(method, options);
}
runtime_1.assertNever(kind);
}
exports.stackIntercept = stackIntercept;
/**
* @deprecated replaced by `stackIntercept()`, still here to support older generated code
*/
function stackUnaryInterceptors(transport, method, input, options) {
return stackIntercept("unary", transport, method, options, input);
}
exports.stackUnaryInterceptors = stackUnaryInterceptors;
/**
* @deprecated replaced by `stackIntercept()`, still here to support older generated code
*/
function stackServerStreamingInterceptors(transport, method, input, options) {
return stackIntercept("serverStreaming", transport, method, options, input);
}
exports.stackServerStreamingInterceptors = stackServerStreamingInterceptors;
/**
* @deprecated replaced by `stackIntercept()`, still here to support older generated code
*/
function stackClientStreamingInterceptors(transport, method, options) {
return stackIntercept("clientStreaming", transport, method, options);
}
exports.stackClientStreamingInterceptors = stackClientStreamingInterceptors;
/**
* @deprecated replaced by `stackIntercept()`, still here to support older generated code
*/
function stackDuplexStreamingInterceptors(transport, method, options) {
return stackIntercept("duplex", transport, method, options);
}
exports.stackDuplexStreamingInterceptors = stackDuplexStreamingInterceptors;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeRpcOptions = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
/**
* Merges custom RPC options with defaults. Returns a new instance and keeps
* the "defaults" and the "options" unmodified.
*
* Merges `RpcMetadata` "meta", overwriting values from "defaults" with
* values from "options". Does not append values to existing entries.
*
* Merges "jsonOptions", including "jsonOptions.typeRegistry", by creating
* a new array that contains types from "options.jsonOptions.typeRegistry"
* first, then types from "defaults.jsonOptions.typeRegistry".
*
* Merges "binaryOptions".
*
* Merges "interceptors" by creating a new array that contains interceptors
* from "defaults" first, then interceptors from "options".
*
* Works with objects that extend `RpcOptions`, but only if the added
* properties are of type Date, primitive like string, boolean, or Array
* of primitives. If you have other property types, you have to merge them
* yourself.
*/
function mergeRpcOptions(defaults, options) {
if (!options)
return defaults;
let o = {};
copy(defaults, o);
copy(options, o);
for (let key of Object.keys(options)) {
let val = options[key];
switch (key) {
case "jsonOptions":
o.jsonOptions = runtime_1.mergeJsonOptions(defaults.jsonOptions, o.jsonOptions);
break;
case "binaryOptions":
o.binaryOptions = runtime_1.mergeBinaryOptions(defaults.binaryOptions, o.binaryOptions);
break;
case "meta":
o.meta = {};
copy(defaults.meta, o.meta);
copy(options.meta, o.meta);
break;
case "interceptors":
o.interceptors = defaults.interceptors ? defaults.interceptors.concat(val) : val.concat();
break;
}
}
return o;
}
exports.mergeRpcOptions = mergeRpcOptions;
function copy(a, into) {
if (!a)
return;
let c = into;
for (let [k, v] of Object.entries(a)) {
if (v instanceof Date)
c[k] = new Date(v.getTime());
else if (Array.isArray(v))
c[k] = v.concat();
else
c[k] = v;
}
}

View file

@ -0,0 +1,172 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcOutputStreamController = void 0;
const deferred_1 = require("./deferred");
const runtime_1 = require("@protobuf-ts/runtime");
/**
* A `RpcOutputStream` that you control.
*/
class RpcOutputStreamController {
constructor() {
this._lis = {
nxt: [],
msg: [],
err: [],
cmp: [],
};
this._closed = false;
}
// --- RpcOutputStream callback API
onNext(callback) {
return this.addLis(callback, this._lis.nxt);
}
onMessage(callback) {
return this.addLis(callback, this._lis.msg);
}
onError(callback) {
return this.addLis(callback, this._lis.err);
}
onComplete(callback) {
return this.addLis(callback, this._lis.cmp);
}
addLis(callback, list) {
list.push(callback);
return () => {
let i = list.indexOf(callback);
if (i >= 0)
list.splice(i, 1);
};
}
// remove all listeners
clearLis() {
for (let l of Object.values(this._lis))
l.splice(0, l.length);
}
// --- Controller API
/**
* Is this stream already closed by a completion or error?
*/
get closed() {
return this._closed !== false;
}
/**
* Emit message, close with error, or close successfully, but only one
* at a time.
* Can be used to wrap a stream by using the other stream's `onNext`.
*/
notifyNext(message, error, complete) {
runtime_1.assert((message ? 1 : 0) + (error ? 1 : 0) + (complete ? 1 : 0) <= 1, 'only one emission at a time');
if (message)
this.notifyMessage(message);
if (error)
this.notifyError(error);
if (complete)
this.notifyComplete();
}
/**
* Emits a new message. Throws if stream is closed.
*
* Triggers onNext and onMessage callbacks.
*/
notifyMessage(message) {
runtime_1.assert(!this.closed, 'stream is closed');
this.pushIt({ value: message, done: false });
this._lis.msg.forEach(l => l(message));
this._lis.nxt.forEach(l => l(message, undefined, false));
}
/**
* Closes the stream with an error. Throws if stream is closed.
*
* Triggers onNext and onError callbacks.
*/
notifyError(error) {
runtime_1.assert(!this.closed, 'stream is closed');
this._closed = error;
this.pushIt(error);
this._lis.err.forEach(l => l(error));
this._lis.nxt.forEach(l => l(undefined, error, false));
this.clearLis();
}
/**
* Closes the stream successfully. Throws if stream is closed.
*
* Triggers onNext and onComplete callbacks.
*/
notifyComplete() {
runtime_1.assert(!this.closed, 'stream is closed');
this._closed = true;
this.pushIt({ value: null, done: true });
this._lis.cmp.forEach(l => l());
this._lis.nxt.forEach(l => l(undefined, undefined, true));
this.clearLis();
}
/**
* Creates an async iterator (that can be used with `for await {...}`)
* to consume the stream.
*
* Some things to note:
* - If an error occurs, the `for await` will throw it.
* - If an error occurred before the `for await` was started, `for await`
* will re-throw it.
* - If the stream is already complete, the `for await` will be empty.
* - If your `for await` consumes slower than the stream produces,
* for example because you are relaying messages in a slow operation,
* messages are queued.
*/
[Symbol.asyncIterator]() {
// init the iterator state, enabling pushIt()
if (!this._itState) {
this._itState = { q: [] };
}
// if we are closed, we are definitely not receiving any more messages.
// but we can't let the iterator get stuck. we want to either:
// a) finish the new iterator immediately, because we are completed
// b) reject the new iterator, because we errored
if (this._closed === true)
this.pushIt({ value: null, done: true });
else if (this._closed !== false)
this.pushIt(this._closed);
// the async iterator
return {
next: () => {
let state = this._itState;
runtime_1.assert(state, "bad state"); // if we don't have a state here, code is broken
// there should be no pending result.
// did the consumer call next() before we resolved our previous result promise?
runtime_1.assert(!state.p, "iterator contract broken");
// did we produce faster than the iterator consumed?
// return the oldest result from the queue.
let first = state.q.shift();
if (first)
return ("value" in first) ? Promise.resolve(first) : Promise.reject(first);
// we have no result ATM, but we promise one.
// as soon as we have a result, we must resolve promise.
state.p = new deferred_1.Deferred();
return state.p.promise;
},
};
}
// "push" a new iterator result.
// this either resolves a pending promise, or enqueues the result.
pushIt(result) {
let state = this._itState;
if (!state)
return;
// is the consumer waiting for us?
if (state.p) {
// yes, consumer is waiting for this promise.
const p = state.p;
runtime_1.assert(p.state == deferred_1.DeferredState.PENDING, "iterator contract broken");
// resolve the promise
("value" in result) ? p.resolve(result) : p.reject(result);
// must cleanup, otherwise iterator.next() would pick it up again.
delete state.p;
}
else {
// we are producing faster than the iterator consumes.
// push result onto queue.
state.q.push(result);
}
}
}
exports.RpcOutputStreamController = RpcOutputStreamController;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerCallContextController = void 0;
class ServerCallContextController {
constructor(method, headers, deadline, sendResponseHeadersFn, defaultStatus = { code: 'OK', detail: '' }) {
this._cancelled = false;
this._listeners = [];
this.method = method;
this.headers = headers;
this.deadline = deadline;
this.trailers = {};
this._sendRH = sendResponseHeadersFn;
this.status = defaultStatus;
}
/**
* Set the call cancelled.
*
* Invokes all callbacks registered with onCancel() and
* sets `cancelled = true`.
*/
notifyCancelled() {
if (!this._cancelled) {
this._cancelled = true;
for (let l of this._listeners) {
l();
}
}
}
/**
* Send response headers.
*/
sendResponseHeaders(data) {
this._sendRH(data);
}
/**
* Is the call cancelled?
*
* When the client closes the connection before the server
* is done, the call is cancelled.
*
* If you want to cancel a request on the server, throw a
* RpcError with the CANCELLED status code.
*/
get cancelled() {
return this._cancelled;
}
/**
* Add a callback for cancellation.
*/
onCancel(callback) {
const l = this._listeners;
l.push(callback);
return () => {
let i = l.indexOf(callback);
if (i >= 0)
l.splice(i, 1);
};
}
}
exports.ServerCallContextController = ServerCallContextController;

View file

@ -0,0 +1,50 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerStreamingCall = void 0;
/**
* A server streaming RPC call. The client provides exactly one input message
* but the server may respond with 0, 1, or more messages.
*/
class ServerStreamingCall {
constructor(method, requestHeaders, request, headers, response, status, trailers) {
this.method = method;
this.requestHeaders = requestHeaders;
this.request = request;
this.headers = headers;
this.responses = response;
this.status = status;
this.trailers = trailers;
}
/**
* Instead of awaiting the response status and trailers, you can
* just as well await this call itself to receive the server outcome.
* You should first setup some listeners to the `request` to
* see the actual messages the server replied with.
*/
then(onfulfilled, onrejected) {
return this.promiseFinished().then(value => onfulfilled ? Promise.resolve(onfulfilled(value)) : value, reason => onrejected ? Promise.resolve(onrejected(reason)) : Promise.reject(reason));
}
promiseFinished() {
return __awaiter(this, void 0, void 0, function* () {
let [headers, status, trailers] = yield Promise.all([this.headers, this.status, this.trailers]);
return {
method: this.method,
requestHeaders: this.requestHeaders,
request: this.request,
headers,
status,
trailers,
};
});
}
}
exports.ServerStreamingCall = ServerStreamingCall;

View file

@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceType = void 0;
const reflection_info_1 = require("./reflection-info");
class ServiceType {
constructor(typeName, methods, options) {
this.typeName = typeName;
this.methods = methods.map(i => reflection_info_1.normalizeMethodInfo(i, this));
this.options = options !== null && options !== void 0 ? options : {};
}
}
exports.ServiceType = ServiceType;

View file

@ -0,0 +1,321 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestTransport = void 0;
const rpc_error_1 = require("./rpc-error");
const runtime_1 = require("@protobuf-ts/runtime");
const rpc_output_stream_1 = require("./rpc-output-stream");
const rpc_options_1 = require("./rpc-options");
const unary_call_1 = require("./unary-call");
const server_streaming_call_1 = require("./server-streaming-call");
const client_streaming_call_1 = require("./client-streaming-call");
const duplex_streaming_call_1 = require("./duplex-streaming-call");
/**
* Transport for testing.
*/
class TestTransport {
/**
* Initialize with mock data. Omitted fields have default value.
*/
constructor(data) {
/**
* Suppress warning / error about uncaught rejections of
* "status" and "trailers".
*/
this.suppressUncaughtRejections = true;
this.headerDelay = 10;
this.responseDelay = 50;
this.betweenResponseDelay = 10;
this.afterResponseDelay = 10;
this.data = data !== null && data !== void 0 ? data : {};
}
/**
* Sent message(s) during the last operation.
*/
get sentMessages() {
if (this.lastInput instanceof TestInputStream) {
return this.lastInput.sent;
}
else if (typeof this.lastInput == "object") {
return [this.lastInput.single];
}
return [];
}
/**
* Sending message(s) completed?
*/
get sendComplete() {
if (this.lastInput instanceof TestInputStream) {
return this.lastInput.completed;
}
else if (typeof this.lastInput == "object") {
return true;
}
return false;
}
// Creates a promise for response headers from the mock data.
promiseHeaders() {
var _a;
const headers = (_a = this.data.headers) !== null && _a !== void 0 ? _a : TestTransport.defaultHeaders;
return headers instanceof rpc_error_1.RpcError
? Promise.reject(headers)
: Promise.resolve(headers);
}
// Creates a promise for a single, valid, message from the mock data.
promiseSingleResponse(method) {
if (this.data.response instanceof rpc_error_1.RpcError) {
return Promise.reject(this.data.response);
}
let r;
if (Array.isArray(this.data.response)) {
runtime_1.assert(this.data.response.length > 0);
r = this.data.response[0];
}
else if (this.data.response !== undefined) {
r = this.data.response;
}
else {
r = method.O.create();
}
runtime_1.assert(method.O.is(r));
return Promise.resolve(r);
}
/**
* Pushes response messages from the mock data to the output stream.
* If an error response, status or trailers are mocked, the stream is
* closed with the respective error.
* Otherwise, stream is completed successfully.
*
* The returned promise resolves when the stream is closed. It should
* not reject. If it does, code is broken.
*/
streamResponses(method, stream, abort) {
return __awaiter(this, void 0, void 0, function* () {
// normalize "data.response" into an array of valid output messages
const messages = [];
if (this.data.response === undefined) {
messages.push(method.O.create());
}
else if (Array.isArray(this.data.response)) {
for (let msg of this.data.response) {
runtime_1.assert(method.O.is(msg));
messages.push(msg);
}
}
else if (!(this.data.response instanceof rpc_error_1.RpcError)) {
runtime_1.assert(method.O.is(this.data.response));
messages.push(this.data.response);
}
// start the stream with an initial delay.
// if the request is cancelled, notify() error and exit.
try {
yield delay(this.responseDelay, abort)(undefined);
}
catch (error) {
stream.notifyError(error);
return;
}
// if error response was mocked, notify() error (stream is now closed with error) and exit.
if (this.data.response instanceof rpc_error_1.RpcError) {
stream.notifyError(this.data.response);
return;
}
// regular response messages were mocked. notify() them.
for (let msg of messages) {
stream.notifyMessage(msg);
// add a short delay between responses
// if the request is cancelled, notify() error and exit.
try {
yield delay(this.betweenResponseDelay, abort)(undefined);
}
catch (error) {
stream.notifyError(error);
return;
}
}
// error status was mocked, notify() error (stream is now closed with error) and exit.
if (this.data.status instanceof rpc_error_1.RpcError) {
stream.notifyError(this.data.status);
return;
}
// error trailers were mocked, notify() error (stream is now closed with error) and exit.
if (this.data.trailers instanceof rpc_error_1.RpcError) {
stream.notifyError(this.data.trailers);
return;
}
// stream completed successfully
stream.notifyComplete();
});
}
// Creates a promise for response status from the mock data.
promiseStatus() {
var _a;
const status = (_a = this.data.status) !== null && _a !== void 0 ? _a : TestTransport.defaultStatus;
return status instanceof rpc_error_1.RpcError
? Promise.reject(status)
: Promise.resolve(status);
}
// Creates a promise for response trailers from the mock data.
promiseTrailers() {
var _a;
const trailers = (_a = this.data.trailers) !== null && _a !== void 0 ? _a : TestTransport.defaultTrailers;
return trailers instanceof rpc_error_1.RpcError
? Promise.reject(trailers)
: Promise.resolve(trailers);
}
maybeSuppressUncaught(...promise) {
if (this.suppressUncaughtRejections) {
for (let p of promise) {
p.catch(() => {
});
}
}
}
mergeOptions(options) {
return rpc_options_1.mergeRpcOptions({}, options);
}
unary(method, input, options) {
var _a;
const requestHeaders = (_a = options.meta) !== null && _a !== void 0 ? _a : {}, headersPromise = this.promiseHeaders()
.then(delay(this.headerDelay, options.abort)), responsePromise = headersPromise
.catch(_ => {
})
.then(delay(this.responseDelay, options.abort))
.then(_ => this.promiseSingleResponse(method)), statusPromise = responsePromise
.catch(_ => {
})
.then(delay(this.afterResponseDelay, options.abort))
.then(_ => this.promiseStatus()), trailersPromise = responsePromise
.catch(_ => {
})
.then(delay(this.afterResponseDelay, options.abort))
.then(_ => this.promiseTrailers());
this.maybeSuppressUncaught(statusPromise, trailersPromise);
this.lastInput = { single: input };
return new unary_call_1.UnaryCall(method, requestHeaders, input, headersPromise, responsePromise, statusPromise, trailersPromise);
}
serverStreaming(method, input, options) {
var _a;
const requestHeaders = (_a = options.meta) !== null && _a !== void 0 ? _a : {}, headersPromise = this.promiseHeaders()
.then(delay(this.headerDelay, options.abort)), outputStream = new rpc_output_stream_1.RpcOutputStreamController(), responseStreamClosedPromise = headersPromise
.then(delay(this.responseDelay, options.abort))
.catch(() => {
})
.then(() => this.streamResponses(method, outputStream, options.abort))
.then(delay(this.afterResponseDelay, options.abort)), statusPromise = responseStreamClosedPromise
.then(() => this.promiseStatus()), trailersPromise = responseStreamClosedPromise
.then(() => this.promiseTrailers());
this.maybeSuppressUncaught(statusPromise, trailersPromise);
this.lastInput = { single: input };
return new server_streaming_call_1.ServerStreamingCall(method, requestHeaders, input, headersPromise, outputStream, statusPromise, trailersPromise);
}
clientStreaming(method, options) {
var _a;
const requestHeaders = (_a = options.meta) !== null && _a !== void 0 ? _a : {}, headersPromise = this.promiseHeaders()
.then(delay(this.headerDelay, options.abort)), responsePromise = headersPromise
.catch(_ => {
})
.then(delay(this.responseDelay, options.abort))
.then(_ => this.promiseSingleResponse(method)), statusPromise = responsePromise
.catch(_ => {
})
.then(delay(this.afterResponseDelay, options.abort))
.then(_ => this.promiseStatus()), trailersPromise = responsePromise
.catch(_ => {
})
.then(delay(this.afterResponseDelay, options.abort))
.then(_ => this.promiseTrailers());
this.maybeSuppressUncaught(statusPromise, trailersPromise);
this.lastInput = new TestInputStream(this.data, options.abort);
return new client_streaming_call_1.ClientStreamingCall(method, requestHeaders, this.lastInput, headersPromise, responsePromise, statusPromise, trailersPromise);
}
duplex(method, options) {
var _a;
const requestHeaders = (_a = options.meta) !== null && _a !== void 0 ? _a : {}, headersPromise = this.promiseHeaders()
.then(delay(this.headerDelay, options.abort)), outputStream = new rpc_output_stream_1.RpcOutputStreamController(), responseStreamClosedPromise = headersPromise
.then(delay(this.responseDelay, options.abort))
.catch(() => {
})
.then(() => this.streamResponses(method, outputStream, options.abort))
.then(delay(this.afterResponseDelay, options.abort)), statusPromise = responseStreamClosedPromise
.then(() => this.promiseStatus()), trailersPromise = responseStreamClosedPromise
.then(() => this.promiseTrailers());
this.maybeSuppressUncaught(statusPromise, trailersPromise);
this.lastInput = new TestInputStream(this.data, options.abort);
return new duplex_streaming_call_1.DuplexStreamingCall(method, requestHeaders, this.lastInput, headersPromise, outputStream, statusPromise, trailersPromise);
}
}
exports.TestTransport = TestTransport;
TestTransport.defaultHeaders = {
responseHeader: "test"
};
TestTransport.defaultStatus = {
code: "OK", detail: "all good"
};
TestTransport.defaultTrailers = {
responseTrailer: "test"
};
function delay(ms, abort) {
return (v) => new Promise((resolve, reject) => {
if (abort === null || abort === void 0 ? void 0 : abort.aborted) {
reject(new rpc_error_1.RpcError("user cancel", "CANCELLED"));
}
else {
const id = setTimeout(() => resolve(v), ms);
if (abort) {
abort.addEventListener("abort", ev => {
clearTimeout(id);
reject(new rpc_error_1.RpcError("user cancel", "CANCELLED"));
});
}
}
});
}
class TestInputStream {
constructor(data, abort) {
this._completed = false;
this._sent = [];
this.data = data;
this.abort = abort;
}
get sent() {
return this._sent;
}
get completed() {
return this._completed;
}
send(message) {
if (this.data.inputMessage instanceof rpc_error_1.RpcError) {
return Promise.reject(this.data.inputMessage);
}
const delayMs = this.data.inputMessage === undefined
? 10
: this.data.inputMessage;
return Promise.resolve(undefined)
.then(() => {
this._sent.push(message);
})
.then(delay(delayMs, this.abort));
}
complete() {
if (this.data.inputComplete instanceof rpc_error_1.RpcError) {
return Promise.reject(this.data.inputComplete);
}
const delayMs = this.data.inputComplete === undefined
? 10
: this.data.inputComplete;
return Promise.resolve(undefined)
.then(() => {
this._completed = true;
})
.then(delay(delayMs, this.abort));
}
}

View file

@ -0,0 +1,49 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnaryCall = void 0;
/**
* A unary RPC call. Unary means there is exactly one input message and
* exactly one output message unless an error occurred.
*/
class UnaryCall {
constructor(method, requestHeaders, request, headers, response, status, trailers) {
this.method = method;
this.requestHeaders = requestHeaders;
this.request = request;
this.headers = headers;
this.response = response;
this.status = status;
this.trailers = trailers;
}
/**
* If you are only interested in the final outcome of this call,
* you can await it to receive a `FinishedUnaryCall`.
*/
then(onfulfilled, onrejected) {
return this.promiseFinished().then(value => onfulfilled ? Promise.resolve(onfulfilled(value)) : value, reason => onrejected ? Promise.resolve(onrejected(reason)) : Promise.reject(reason));
}
promiseFinished() {
return __awaiter(this, void 0, void 0, function* () {
let [headers, response, status, trailers] = yield Promise.all([this.headers, this.response, this.status, this.trailers]);
return {
method: this.method,
requestHeaders: this.requestHeaders,
request: this.request,
headers,
response,
status,
trailers
};
});
}
}
exports.UnaryCall = UnaryCall;