skir-client 0.1.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/skir-client.d.ts +311 -21
- package/dist/cjs/skir-client.d.ts.map +1 -1
- package/dist/cjs/skir-client.js +187 -84
- package/dist/cjs/skir-client.js.map +1 -1
- package/dist/esm/skir-client.d.ts +311 -21
- package/dist/esm/skir-client.d.ts.map +1 -1
- package/dist/esm/skir-client.js +185 -82
- package/dist/esm/skir-client.js.map +1 -1
- package/package.json +1 -1
- package/src/skir-client.ts +488 -121
package/dist/cjs/skir-client.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports._initModuleClasses = exports.installServiceOnExpressApp = exports.Service = exports.
|
|
12
|
+
exports._initModuleClasses = exports.installServiceOnExpressApp = exports.Service = exports.ServiceError = exports.ServiceClient = exports._EnumBase = exports._FrozenBase = exports._toFrozenArray = exports._EMPTY_ARRAY = exports.parseTypeDescriptorFromJsonCode = exports.parseTypeDescriptorFromJson = exports.optionalSerializer = exports.arraySerializer = exports.primitiveSerializer = exports.ByteString = exports.Timestamp = void 0;
|
|
13
13
|
/**
|
|
14
14
|
* A single moment in time represented in a platform-independent format, with a
|
|
15
15
|
* precision of one millisecond.
|
|
@@ -1867,7 +1867,6 @@ class ServiceClient {
|
|
|
1867
1867
|
/** Invokes the given method on the remote server through an RPC. */
|
|
1868
1868
|
invokeRemote(method, request, httpMethod = "POST") {
|
|
1869
1869
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1870
|
-
this.lastRespHeaders = undefined;
|
|
1871
1870
|
const requestJson = method.requestSerializer.toJsonCode(request);
|
|
1872
1871
|
const requestBody = [method.name, method.number, "", requestJson].join(":");
|
|
1873
1872
|
const requestInit = Object.assign({}, (yield Promise.resolve(this.getRequestMetadata(method))));
|
|
@@ -1880,7 +1879,6 @@ class ServiceClient {
|
|
|
1880
1879
|
url.search = requestBody.replace(/%/g, "%25");
|
|
1881
1880
|
}
|
|
1882
1881
|
const httpResponse = yield fetch(url, requestInit);
|
|
1883
|
-
this.lastRespHeaders = httpResponse.headers;
|
|
1884
1882
|
const responseData = yield httpResponse.blob();
|
|
1885
1883
|
if (httpResponse.ok) {
|
|
1886
1884
|
const jsonCode = yield responseData.text();
|
|
@@ -1895,77 +1893,135 @@ class ServiceClient {
|
|
|
1895
1893
|
}
|
|
1896
1894
|
});
|
|
1897
1895
|
}
|
|
1898
|
-
get lastResponseHeaders() {
|
|
1899
|
-
return this.lastRespHeaders;
|
|
1900
|
-
}
|
|
1901
1896
|
}
|
|
1902
1897
|
exports.ServiceClient = ServiceClient;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
case "server-error":
|
|
1917
|
-
return 500;
|
|
1918
|
-
default: {
|
|
1919
|
-
const _ = this.type;
|
|
1920
|
-
throw new Error(_);
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
get contentType() {
|
|
1925
|
-
switch (this.type) {
|
|
1926
|
-
case "ok-json":
|
|
1927
|
-
return "application/json";
|
|
1928
|
-
case "ok-html":
|
|
1929
|
-
return "text/html; charset=utf-8";
|
|
1930
|
-
case "bad-request":
|
|
1931
|
-
case "server-error":
|
|
1932
|
-
return "text/plain; charset=utf-8";
|
|
1933
|
-
default: {
|
|
1934
|
-
const _ = this.type;
|
|
1935
|
-
throw new Error(_);
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1898
|
+
function makeOkJsonResponse(data) {
|
|
1899
|
+
return {
|
|
1900
|
+
data: data,
|
|
1901
|
+
statusCode: 200,
|
|
1902
|
+
contentType: "application/json",
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
function makeOkHtmlResponse(data) {
|
|
1906
|
+
return {
|
|
1907
|
+
data: data,
|
|
1908
|
+
statusCode: 200,
|
|
1909
|
+
contentType: "text/html; charset=utf-8",
|
|
1910
|
+
};
|
|
1939
1911
|
}
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1912
|
+
function makeBadRequestResponse(data) {
|
|
1913
|
+
return {
|
|
1914
|
+
data: data,
|
|
1915
|
+
statusCode: 400,
|
|
1916
|
+
contentType: "text/plain; charset=utf-8",
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
function makeServerErrorResponse(data, statusCode = 500) {
|
|
1920
|
+
return {
|
|
1921
|
+
data: data,
|
|
1922
|
+
statusCode: statusCode,
|
|
1923
|
+
contentType: "text/plain; charset=utf-8",
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
function getStudioHtml(studioAppJsUrl) {
|
|
1927
|
+
// Copied from
|
|
1928
|
+
// https://github.com/gepheum/skir-studio/blob/main/index.jsdeliver.html
|
|
1929
|
+
return `<!DOCTYPE html>
|
|
1944
1930
|
|
|
1945
1931
|
<html>
|
|
1946
1932
|
<head>
|
|
1947
1933
|
<meta charset="utf-8" />
|
|
1948
1934
|
<title>RESTudio</title>
|
|
1949
|
-
<script src="
|
|
1935
|
+
<script src="${studioAppJsUrl}"></script>
|
|
1950
1936
|
</head>
|
|
1951
1937
|
<body style="margin: 0; padding: 0;">
|
|
1952
1938
|
<restudio-app></restudio-app>
|
|
1953
1939
|
</body>
|
|
1954
1940
|
</html>
|
|
1955
1941
|
`;
|
|
1942
|
+
}
|
|
1943
|
+
/**
|
|
1944
|
+
* If this error is thrown from a method implementation, the specified status
|
|
1945
|
+
* code and message will be returned in the HTTP response.
|
|
1946
|
+
*
|
|
1947
|
+
* If any other type of exception is thrown, the response status code will be
|
|
1948
|
+
* 500 (Internal Server Error).
|
|
1949
|
+
*/
|
|
1950
|
+
class ServiceError extends Error {
|
|
1951
|
+
constructor(spec) {
|
|
1952
|
+
var _a;
|
|
1953
|
+
super((_a = spec.message) !== null && _a !== void 0 ? _a : spec.desc);
|
|
1954
|
+
this.spec = spec;
|
|
1955
|
+
}
|
|
1956
|
+
toRawResponse() {
|
|
1957
|
+
var _a;
|
|
1958
|
+
return makeServerErrorResponse((_a = this.spec.message) !== null && _a !== void 0 ? _a : this.spec.desc, this.spec.statusCode);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
exports.ServiceError = ServiceError;
|
|
1956
1962
|
/**
|
|
1957
1963
|
* Implementation of a skir service.
|
|
1958
1964
|
*
|
|
1959
1965
|
* Usage: call `.addMethod()` to register methods, then install the service on
|
|
1960
1966
|
* an HTTP server either by:
|
|
1961
|
-
* - calling the `installServiceOnExpressApp()` top-level function
|
|
1967
|
+
* - calling the `installServiceOnExpressApp()` top-level function if you are
|
|
1962
1968
|
* using ExpressJS
|
|
1963
1969
|
* - writing your own implementation of `installServiceOn*()` which calls
|
|
1964
1970
|
* `.handleRequest()` if you are using another web application framework
|
|
1971
|
+
*
|
|
1972
|
+
* ## Handling Request Metadata
|
|
1973
|
+
*
|
|
1974
|
+
* The `RequestMeta` type parameter specifies what metadata (authentication,
|
|
1975
|
+
* headers, etc.) your method implementations receive. There are two approaches:
|
|
1976
|
+
*
|
|
1977
|
+
* ### Approach 1: Use the framework's request type directly
|
|
1978
|
+
*
|
|
1979
|
+
* Set `RequestMeta` to your framework's request type (e.g., `ExpressRequest`).
|
|
1980
|
+
* All method implementations will receive the full framework request object.
|
|
1981
|
+
*
|
|
1982
|
+
* ```typescript
|
|
1983
|
+
* const service = new Service<ExpressRequest>();
|
|
1984
|
+
* service.addMethod(myMethod, async (req, expressReq) => {
|
|
1985
|
+
* const isAdmin = expressReq.user?.role === 'admin';
|
|
1986
|
+
* // ...
|
|
1987
|
+
* });
|
|
1988
|
+
* installServiceOnExpressApp(app, '/api', service, text, json);
|
|
1989
|
+
* ```
|
|
1990
|
+
*
|
|
1991
|
+
* ### Approach 2: Use a simplified custom type (recommended for testing)
|
|
1992
|
+
*
|
|
1993
|
+
* Set `RequestMeta` to a minimal type containing only what your service needs.
|
|
1994
|
+
* Use `withRequestMeta()` to extract this data from the framework request when
|
|
1995
|
+
* installing the service.
|
|
1996
|
+
*
|
|
1997
|
+
* ```typescript
|
|
1998
|
+
* const service = new Service<{ isAdmin: boolean }>();
|
|
1999
|
+
* service.addMethod(myMethod, async (req, { isAdmin }) => {
|
|
2000
|
+
* // Implementation is framework-agnostic and easy to unit test
|
|
2001
|
+
* if (!isAdmin) throw new ServiceError({ statusCode: 403, desc: "Forbidden" });
|
|
2002
|
+
* // ...
|
|
2003
|
+
* });
|
|
2004
|
+
*
|
|
2005
|
+
* // Adapt to Express when installing
|
|
2006
|
+
* const handler = service.withRequestMeta((req: ExpressRequest) => ({
|
|
2007
|
+
* isAdmin: req.user?.role === 'admin'
|
|
2008
|
+
* }));
|
|
2009
|
+
* installServiceOnExpressApp(app, '/api', handler, text, json);
|
|
2010
|
+
* ```
|
|
2011
|
+
*
|
|
2012
|
+
* This approach decouples your service from the HTTP framework, making it easier
|
|
2013
|
+
* to test and clearer about what request data it actually uses.
|
|
1965
2014
|
*/
|
|
1966
2015
|
class Service {
|
|
1967
|
-
constructor() {
|
|
2016
|
+
constructor(options) {
|
|
2017
|
+
var _a, _b, _c, _d;
|
|
1968
2018
|
this.methodImpls = {};
|
|
2019
|
+
this.options = {
|
|
2020
|
+
keepUnrecognizedValues: (_a = options === null || options === void 0 ? void 0 : options.keepUnrecognizedValues) !== null && _a !== void 0 ? _a : DEFAULT_SERVICE_OPTIONS.keepUnrecognizedValues,
|
|
2021
|
+
canCopyUnknownErrorMessageToResponse: (_b = options === null || options === void 0 ? void 0 : options.canCopyUnknownErrorMessageToResponse) !== null && _b !== void 0 ? _b : DEFAULT_SERVICE_OPTIONS.canCopyUnknownErrorMessageToResponse,
|
|
2022
|
+
errorLogger: (_c = options === null || options === void 0 ? void 0 : options.errorLogger) !== null && _c !== void 0 ? _c : DEFAULT_SERVICE_OPTIONS.errorLogger,
|
|
2023
|
+
studioAppJsUrl: new URL((_d = options === null || options === void 0 ? void 0 : options.studioAppJsUrl) !== null && _d !== void 0 ? _d : DEFAULT_SERVICE_OPTIONS.studioAppJsUrl).toString(),
|
|
2024
|
+
};
|
|
1969
2025
|
}
|
|
1970
2026
|
addMethod(method, impl) {
|
|
1971
2027
|
const { number } = method;
|
|
@@ -1978,20 +2034,7 @@ class Service {
|
|
|
1978
2034
|
};
|
|
1979
2035
|
return this;
|
|
1980
2036
|
}
|
|
1981
|
-
|
|
1982
|
-
* Parses the content of a user request and invokes the appropriate method.
|
|
1983
|
-
* If you are using ExpressJS as your web application framework, you don't
|
|
1984
|
-
* need to call this method, you can simply call the
|
|
1985
|
-
* `installServiceOnExpressApp()` top-level function.
|
|
1986
|
-
*
|
|
1987
|
-
* If the request is a GET request, pass in the decoded query string as the
|
|
1988
|
-
* request's body. The query string is the part of the URL after '?', and it
|
|
1989
|
-
* can be decoded with DecodeURIComponent.
|
|
1990
|
-
*
|
|
1991
|
-
* Pass in "keep-unrecognized-values" if the request cannot come from a
|
|
1992
|
-
* malicious user.
|
|
1993
|
-
*/
|
|
1994
|
-
handleRequest(reqBody, reqMeta, resMeta, keepUnrecognizedValues) {
|
|
2037
|
+
handleRequest(reqBody, reqMeta) {
|
|
1995
2038
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1996
2039
|
if (reqBody === "" || reqBody === "list") {
|
|
1997
2040
|
const json = {
|
|
@@ -2004,10 +2047,11 @@ class Service {
|
|
|
2004
2047
|
})),
|
|
2005
2048
|
};
|
|
2006
2049
|
const jsonCode = JSON.stringify(json, undefined, " ");
|
|
2007
|
-
return
|
|
2050
|
+
return makeOkHtmlResponse(jsonCode);
|
|
2008
2051
|
}
|
|
2009
|
-
else if (reqBody === "
|
|
2010
|
-
|
|
2052
|
+
else if (reqBody === "studio") {
|
|
2053
|
+
const studioHtml = getStudioHtml(this.options.studioAppJsUrl);
|
|
2054
|
+
return makeOkHtmlResponse(studioHtml);
|
|
2011
2055
|
}
|
|
2012
2056
|
// Parse request
|
|
2013
2057
|
let methodName;
|
|
@@ -2022,11 +2066,11 @@ class Service {
|
|
|
2022
2066
|
reqBodyJson = JSON.parse(reqBody);
|
|
2023
2067
|
}
|
|
2024
2068
|
catch (_e) {
|
|
2025
|
-
return
|
|
2069
|
+
return makeBadRequestResponse("bad request: invalid JSON");
|
|
2026
2070
|
}
|
|
2027
2071
|
const methodField = reqBodyJson["method"];
|
|
2028
2072
|
if (methodField === undefined) {
|
|
2029
|
-
return
|
|
2073
|
+
return makeBadRequestResponse("bad request: missing 'method' field in JSON");
|
|
2030
2074
|
}
|
|
2031
2075
|
if (typeof methodField === "string") {
|
|
2032
2076
|
methodName = methodField;
|
|
@@ -2037,12 +2081,12 @@ class Service {
|
|
|
2037
2081
|
methodNumber = methodField;
|
|
2038
2082
|
}
|
|
2039
2083
|
else {
|
|
2040
|
-
return
|
|
2084
|
+
return makeBadRequestResponse("bad request: 'method' field must be a string or a number");
|
|
2041
2085
|
}
|
|
2042
2086
|
format = "readable";
|
|
2043
2087
|
const requestField = reqBodyJson["request"];
|
|
2044
2088
|
if (requestField === undefined) {
|
|
2045
|
-
return
|
|
2089
|
+
return makeBadRequestResponse("bad request: missing 'request' field in JSON");
|
|
2046
2090
|
}
|
|
2047
2091
|
requestData = ["json", requestField];
|
|
2048
2092
|
}
|
|
@@ -2050,7 +2094,7 @@ class Service {
|
|
|
2050
2094
|
// A colon-separated string
|
|
2051
2095
|
const match = reqBody.match(/^([^:]*):([^:]*):([^:]*):([\S\s]*)$/);
|
|
2052
2096
|
if (!match) {
|
|
2053
|
-
return
|
|
2097
|
+
return makeBadRequestResponse("bad request: invalid request format");
|
|
2054
2098
|
}
|
|
2055
2099
|
methodName = match[1];
|
|
2056
2100
|
const methodNumberStr = match[2];
|
|
@@ -2058,7 +2102,7 @@ class Service {
|
|
|
2058
2102
|
requestData = ["json-code", match[4]];
|
|
2059
2103
|
if (methodNumberStr) {
|
|
2060
2104
|
if (!/^-?[0-9]+$/.test(methodNumberStr)) {
|
|
2061
|
-
return
|
|
2105
|
+
return makeBadRequestResponse("bad request: can't parse method number");
|
|
2062
2106
|
}
|
|
2063
2107
|
methodNumber = parseInt(methodNumberStr);
|
|
2064
2108
|
}
|
|
@@ -2072,35 +2116,48 @@ class Service {
|
|
|
2072
2116
|
const allMethods = Object.values(this.methodImpls);
|
|
2073
2117
|
const nameMatches = allMethods.filter((m) => m.method.name === methodName);
|
|
2074
2118
|
if (nameMatches.length === 0) {
|
|
2075
|
-
return
|
|
2119
|
+
return makeBadRequestResponse(`bad request: method not found: ${methodName}`);
|
|
2076
2120
|
}
|
|
2077
2121
|
else if (nameMatches.length > 1) {
|
|
2078
|
-
return
|
|
2122
|
+
return makeBadRequestResponse(`bad request: method name '${methodName}' is ambiguous; use method number instead`);
|
|
2079
2123
|
}
|
|
2080
2124
|
methodNumber = nameMatches[0].method.number;
|
|
2081
2125
|
}
|
|
2082
2126
|
const methodImpl = this.methodImpls[methodNumber];
|
|
2083
2127
|
if (!methodImpl) {
|
|
2084
|
-
return
|
|
2128
|
+
return makeBadRequestResponse(`bad request: method not found: ${methodName}; number: ${methodNumber}`);
|
|
2085
2129
|
}
|
|
2086
2130
|
let req;
|
|
2087
2131
|
try {
|
|
2088
2132
|
if (requestData[0] == "json") {
|
|
2089
|
-
req = methodImpl.method.requestSerializer.fromJson(requestData[1], keepUnrecognizedValues
|
|
2133
|
+
req = methodImpl.method.requestSerializer.fromJson(requestData[1], this.options.keepUnrecognizedValues
|
|
2134
|
+
? "keep-unrecognized-values"
|
|
2135
|
+
: undefined);
|
|
2090
2136
|
}
|
|
2091
2137
|
else {
|
|
2092
|
-
req = methodImpl.method.requestSerializer.fromJsonCode(requestData[1], keepUnrecognizedValues
|
|
2138
|
+
req = methodImpl.method.requestSerializer.fromJsonCode(requestData[1], this.options.keepUnrecognizedValues
|
|
2139
|
+
? "keep-unrecognized-values"
|
|
2140
|
+
: undefined);
|
|
2093
2141
|
}
|
|
2094
2142
|
}
|
|
2095
2143
|
catch (e) {
|
|
2096
|
-
return
|
|
2144
|
+
return makeBadRequestResponse(`bad request: can't parse JSON: ${e}`);
|
|
2097
2145
|
}
|
|
2098
2146
|
let res;
|
|
2099
2147
|
try {
|
|
2100
|
-
res = yield methodImpl.impl(req, reqMeta
|
|
2148
|
+
res = yield methodImpl.impl(req, reqMeta);
|
|
2101
2149
|
}
|
|
2102
2150
|
catch (e) {
|
|
2103
|
-
|
|
2151
|
+
this.options.errorLogger(e, methodImpl.method, req, reqMeta);
|
|
2152
|
+
if (e instanceof ServiceError) {
|
|
2153
|
+
return e.toRawResponse();
|
|
2154
|
+
}
|
|
2155
|
+
else {
|
|
2156
|
+
const message = this.options.canCopyUnknownErrorMessageToResponse(reqMeta)
|
|
2157
|
+
? `server error: ${e}`
|
|
2158
|
+
: "server error";
|
|
2159
|
+
return makeServerErrorResponse(message);
|
|
2160
|
+
}
|
|
2104
2161
|
}
|
|
2105
2162
|
let resJson;
|
|
2106
2163
|
try {
|
|
@@ -2108,14 +2165,60 @@ class Service {
|
|
|
2108
2165
|
resJson = methodImpl.method.responseSerializer.toJsonCode(res, flavor);
|
|
2109
2166
|
}
|
|
2110
2167
|
catch (e) {
|
|
2111
|
-
return
|
|
2168
|
+
return makeServerErrorResponse(`server error: can't serialize response to JSON: ${e}`);
|
|
2112
2169
|
}
|
|
2113
|
-
return
|
|
2170
|
+
return makeOkJsonResponse(resJson);
|
|
2114
2171
|
});
|
|
2115
2172
|
}
|
|
2173
|
+
/**
|
|
2174
|
+
* Creates a request handler that extracts simplified request metadata from
|
|
2175
|
+
* framework-specific request objects before passing it to this service.
|
|
2176
|
+
*
|
|
2177
|
+
* This decouples your service implementation from the HTTP framework, making
|
|
2178
|
+
* it easier to unit test (tests don't need to mock framework objects) and
|
|
2179
|
+
* making the service implementation clearer by explicitly declaring exactly
|
|
2180
|
+
* what request data it needs.
|
|
2181
|
+
*
|
|
2182
|
+
* @param transformFn Function that extracts the necessary data from the
|
|
2183
|
+
* framework-specific request object. Can be async or sync.
|
|
2184
|
+
* @returns A request handler that accepts the framework-specific request type.
|
|
2185
|
+
*
|
|
2186
|
+
* @example
|
|
2187
|
+
* ```typescript
|
|
2188
|
+
* // Define a service that only needs to know if the user is an admin
|
|
2189
|
+
*
|
|
2190
|
+
* const service = new Service<{ isAdmin: boolean }>();
|
|
2191
|
+
*
|
|
2192
|
+
* service.addMethod(myMethod, async (req, { isAdmin }) => {
|
|
2193
|
+
* // Implementation is framework-agnostic and easy to test
|
|
2194
|
+
* if (!isAdmin) throw new ServiceError({ statusCode: 403, desc: "Forbidden" });
|
|
2195
|
+
* // ...
|
|
2196
|
+
* });
|
|
2197
|
+
*
|
|
2198
|
+
* // Adapt it to work with Express
|
|
2199
|
+
* const expressHandler = service.withRequestMeta((req: ExpressRequest) => ({
|
|
2200
|
+
* isAdmin: req.user?.role === 'admin'
|
|
2201
|
+
* }));
|
|
2202
|
+
* installServiceOnExpressApp(app, '/api', expressHandler, text, json);
|
|
2203
|
+
* ```
|
|
2204
|
+
*/
|
|
2205
|
+
withRequestMeta(transformFn) {
|
|
2206
|
+
return {
|
|
2207
|
+
handleRequest: (reqBody, reqMeta) => __awaiter(this, void 0, void 0, function* () {
|
|
2208
|
+
const transformedMeta = yield Promise.resolve(transformFn(reqMeta));
|
|
2209
|
+
return this.handleRequest(reqBody, transformedMeta);
|
|
2210
|
+
}),
|
|
2211
|
+
};
|
|
2212
|
+
}
|
|
2116
2213
|
}
|
|
2117
2214
|
exports.Service = Service;
|
|
2118
|
-
|
|
2215
|
+
const DEFAULT_SERVICE_OPTIONS = {
|
|
2216
|
+
keepUnrecognizedValues: false,
|
|
2217
|
+
canCopyUnknownErrorMessageToResponse: () => false,
|
|
2218
|
+
errorLogger: () => { },
|
|
2219
|
+
studioAppJsUrl: "https://cdn.jsdelivr.net/npm/skir-studio/dist/skir-studio-standalone.js",
|
|
2220
|
+
};
|
|
2221
|
+
function installServiceOnExpressApp(app, queryPath, service, text, json) {
|
|
2119
2222
|
const callback = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
2120
2223
|
let body;
|
|
2121
2224
|
const indexOfQuestionMark = req.originalUrl.indexOf("?");
|
|
@@ -2131,7 +2234,7 @@ function installServiceOnExpressApp(app, queryPath, service, text, json, keepUnr
|
|
|
2131
2234
|
? JSON.stringify(req.body)
|
|
2132
2235
|
: "";
|
|
2133
2236
|
}
|
|
2134
|
-
const rawResponse = yield service.handleRequest(body, req
|
|
2237
|
+
const rawResponse = yield service.handleRequest(body, req);
|
|
2135
2238
|
res
|
|
2136
2239
|
.status(rawResponse.statusCode)
|
|
2137
2240
|
.contentType(rawResponse.contentType)
|