@mionjs/client 0.8.0-alpha.0 → 0.8.4
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/index.cjs +1 -1
- package/.dist/cjs/index.d.ts +7 -6
- package/.dist/cjs/src/client.cjs +1 -1
- package/.dist/cjs/src/client.cjs.map +1 -1
- package/.dist/cjs/src/client.d.ts +9 -7
- package/.dist/cjs/src/constants.cjs +1 -1
- package/.dist/cjs/src/constants.cjs.map +1 -1
- package/.dist/cjs/src/constants.d.ts +1 -1
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs +2 -0
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs.map +1 -0
- package/.dist/cjs/src/lib/clientMethodsMetadata.d.ts +10 -0
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs +2 -0
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs.map +1 -0
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.d.ts +2 -0
- package/.dist/cjs/src/{handlersRegistry.cjs → lib/handlersRegistry.cjs} +1 -1
- package/.dist/cjs/src/lib/handlersRegistry.cjs.map +1 -0
- package/.dist/cjs/src/{handlersRegistry.d.ts → lib/handlersRegistry.d.ts} +1 -1
- package/.dist/cjs/src/lib/serializer.cjs +2 -0
- package/.dist/cjs/src/lib/serializer.cjs.map +1 -0
- package/.dist/{esm/src → cjs/src/lib}/serializer.d.ts +3 -5
- package/.dist/cjs/src/lib/storage.cjs +2 -0
- package/.dist/cjs/src/lib/storage.cjs.map +1 -0
- package/.dist/cjs/src/lib/testUtils.cjs +2 -0
- package/.dist/cjs/src/lib/testUtils.cjs.map +1 -0
- package/.dist/cjs/src/lib/typedEvent.cjs +2 -0
- package/.dist/cjs/src/lib/typedEvent.cjs.map +1 -0
- package/.dist/{esm/src → cjs/src/lib}/typedEvent.d.ts +1 -1
- package/.dist/cjs/src/lib/validation.cjs +2 -0
- package/.dist/cjs/src/lib/validation.cjs.map +1 -0
- package/.dist/cjs/src/{validation.d.ts → lib/validation.d.ts} +2 -2
- package/.dist/cjs/src/request.cjs +1 -1
- package/.dist/cjs/src/request.cjs.map +1 -1
- package/.dist/cjs/src/request.d.ts +10 -4
- package/.dist/cjs/src/routesFlow.cjs +1 -1
- package/.dist/cjs/src/routesFlow.cjs.map +1 -1
- package/.dist/cjs/src/routesFlow.d.ts +2 -2
- package/.dist/cjs/src/subRequest.cjs +1 -1
- package/.dist/cjs/src/subRequest.cjs.map +1 -1
- package/.dist/cjs/src/subRequest.d.ts +5 -6
- package/.dist/cjs/src/types.cjs +1 -1
- package/.dist/cjs/src/types.d.ts +55 -64
- package/.dist/esm/index.d.ts +7 -6
- package/.dist/esm/index.js +10 -48
- package/.dist/esm/src/client.d.ts +9 -7
- package/.dist/esm/src/client.js +32 -58
- package/.dist/esm/src/client.js.map +1 -1
- package/.dist/esm/src/constants.d.ts +1 -1
- package/.dist/esm/src/constants.js +1 -1
- package/.dist/esm/src/constants.js.map +1 -1
- package/.dist/esm/src/lib/clientMethodsMetadata.d.ts +10 -0
- package/.dist/esm/src/lib/clientMethodsMetadata.js +125 -0
- package/.dist/esm/src/lib/clientMethodsMetadata.js.map +1 -0
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.d.ts +2 -0
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.js +31 -0
- package/.dist/esm/src/lib/fetchRemoteMethodsMetadata.js.map +1 -0
- package/.dist/esm/src/{handlersRegistry.d.ts → lib/handlersRegistry.d.ts} +1 -1
- package/.dist/esm/src/{handlersRegistry.js → lib/handlersRegistry.js} +0 -5
- package/.dist/esm/src/lib/handlersRegistry.js.map +1 -0
- package/.dist/{cjs/src → esm/src/lib}/serializer.d.ts +3 -5
- package/.dist/esm/src/{serializer.js → lib/serializer.js} +88 -72
- package/.dist/esm/src/lib/serializer.js.map +1 -0
- package/.dist/esm/src/{storage.js → lib/storage.js} +1 -6
- package/.dist/esm/src/lib/storage.js.map +1 -0
- package/.dist/esm/src/lib/testUtils.js +11 -0
- package/.dist/esm/src/lib/testUtils.js.map +1 -0
- package/.dist/{cjs/src → esm/src/lib}/typedEvent.d.ts +1 -1
- package/.dist/esm/src/{typedEvent.js → lib/typedEvent.js} +0 -2
- package/.dist/esm/src/lib/typedEvent.js.map +1 -0
- package/.dist/esm/src/{validation.d.ts → lib/validation.d.ts} +2 -2
- package/.dist/esm/src/{validation.js → lib/validation.js} +3 -10
- package/.dist/esm/src/lib/validation.js.map +1 -0
- package/.dist/esm/src/request.d.ts +10 -4
- package/.dist/esm/src/request.js +123 -78
- package/.dist/esm/src/request.js.map +1 -1
- package/.dist/esm/src/routesFlow.d.ts +2 -2
- package/.dist/esm/src/routesFlow.js +13 -14
- package/.dist/esm/src/routesFlow.js.map +1 -1
- package/.dist/esm/src/subRequest.d.ts +5 -6
- package/.dist/esm/src/subRequest.js +13 -28
- package/.dist/esm/src/subRequest.js.map +1 -1
- package/.dist/esm/src/types.d.ts +55 -64
- package/.dist/esm/src/types.js +1 -41
- package/.dist/esm/src/types.js.map +1 -1
- package/package.json +8 -14
- package/.dist/cjs/_virtual/jit-fns.cjs +0 -315
- package/.dist/cjs/_virtual/jit-fns.cjs.map +0 -1
- package/.dist/cjs/_virtual/pure-fns.cjs +0 -56
- package/.dist/cjs/_virtual/pure-fns.cjs.map +0 -1
- package/.dist/cjs/_virtual/router-cache.cjs +0 -2
- package/.dist/cjs/_virtual/router-cache.cjs.map +0 -1
- package/.dist/cjs/src/aot/loadClientAOTCaches.cjs +0 -2
- package/.dist/cjs/src/aot/loadClientAOTCaches.cjs.map +0 -1
- package/.dist/cjs/src/aot/loadClientAOTCaches.d.ts +0 -8
- package/.dist/cjs/src/clientMethodsMetadata.cjs +0 -2
- package/.dist/cjs/src/clientMethodsMetadata.cjs.map +0 -1
- package/.dist/cjs/src/clientMethodsMetadata.d.ts +0 -10
- package/.dist/cjs/src/handlersRegistry.cjs.map +0 -1
- package/.dist/cjs/src/serializer.cjs +0 -2
- package/.dist/cjs/src/serializer.cjs.map +0 -1
- package/.dist/cjs/src/storage.cjs +0 -2
- package/.dist/cjs/src/storage.cjs.map +0 -1
- package/.dist/cjs/src/testUtils.cjs +0 -2
- package/.dist/cjs/src/testUtils.cjs.map +0 -1
- package/.dist/cjs/src/typedEvent.cjs +0 -2
- package/.dist/cjs/src/typedEvent.cjs.map +0 -1
- package/.dist/cjs/src/validation.cjs +0 -2
- package/.dist/cjs/src/validation.cjs.map +0 -1
- package/.dist/esm/_virtual/jit-fns.js +0 -1391
- package/.dist/esm/_virtual/jit-fns.js.map +0 -1
- package/.dist/esm/_virtual/pure-fns.js +0 -109
- package/.dist/esm/_virtual/pure-fns.js.map +0 -1
- package/.dist/esm/_virtual/router-cache.js +0 -5
- package/.dist/esm/_virtual/router-cache.js.map +0 -1
- package/.dist/esm/src/aot/loadClientAOTCaches.d.ts +0 -8
- package/.dist/esm/src/aot/loadClientAOTCaches.js +0 -19
- package/.dist/esm/src/aot/loadClientAOTCaches.js.map +0 -1
- package/.dist/esm/src/clientMethodsMetadata.d.ts +0 -10
- package/.dist/esm/src/clientMethodsMetadata.js +0 -162
- package/.dist/esm/src/clientMethodsMetadata.js.map +0 -1
- package/.dist/esm/src/handlersRegistry.js.map +0 -1
- package/.dist/esm/src/serializer.js.map +0 -1
- package/.dist/esm/src/storage.js.map +0 -1
- package/.dist/esm/src/testUtils.js +0 -48
- package/.dist/esm/src/testUtils.js.map +0 -1
- package/.dist/esm/src/typedEvent.js.map +0 -1
- package/.dist/esm/src/validation.js.map +0 -1
- /package/.dist/cjs/src/{storage.d.ts → lib/storage.d.ts} +0 -0
- /package/.dist/cjs/src/{testUtils.d.ts → lib/testUtils.d.ts} +0 -0
- /package/.dist/esm/src/{storage.d.ts → lib/storage.d.ts} +0 -0
- /package/.dist/esm/src/{testUtils.d.ts → lib/testUtils.d.ts} +0 -0
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DEFAULT_PREFILL_OPTIONS } from "
|
|
3
|
-
|
|
4
|
-
return fn.__type = args, fn;
|
|
5
|
-
}
|
|
6
|
-
const __ΩSerializedBody = ["SerializedBody", "P&WJw!y"], __ΩContentType = ["application/json; charset=utf-8", "application/octet-stream", "ContentType", 'P.!."Jw#y'], __ΩSerializedRequest = [() => __ΩSerializedBody, "body", () => __ΩContentType, "contentType", "SerializedRequest", 'Pn!4"n#4$Mw%y'];
|
|
7
|
-
function getSerializerMode(req) {
|
|
8
|
-
const methodId = req.route?.id ?? req.workflowSubRequests?.[0]?.id, serializerMode = routesCache.getMethodJitFns(methodId)?.options.serializer || DEFAULT_PREFILL_OPTIONS.serializer;
|
|
9
|
-
return serializerMode === "json" ? DEFAULT_PREFILL_OPTIONS.serializer : serializerMode;
|
|
10
|
-
}
|
|
11
|
-
getSerializerMode.__type = ["MionClientRequest", "req", "SerializerMode", "getSerializerMode", 'P"w!2""w#/$'];
|
|
1
|
+
import { RpcError, deserializeBinaryBody, MION_ROUTES, routesCache, HandlerType, serializeBinaryBody as serializeBinaryBody$1, isRpcError } from "@mionjs/core";
|
|
2
|
+
import { DEFAULT_PREFILL_OPTIONS } from "../constants.js";
|
|
3
|
+
import { extractAndProcessMetadata } from "./clientMethodsMetadata.js";
|
|
12
4
|
function serializeRequestBody(req) {
|
|
13
5
|
const serializerMode = getSerializerMode(req);
|
|
14
6
|
switch (serializerMode) {
|
|
15
7
|
case "json":
|
|
16
8
|
case "stringifyJson":
|
|
17
9
|
return {
|
|
18
|
-
body:
|
|
10
|
+
body: serializeJsonBody(req),
|
|
11
|
+
contentType: "application/json; charset=utf-8"
|
|
12
|
+
};
|
|
13
|
+
case "optimistic":
|
|
14
|
+
return {
|
|
15
|
+
body: serializeJSonBodyOptimistic(req),
|
|
19
16
|
contentType: "application/json; charset=utf-8"
|
|
20
17
|
};
|
|
21
18
|
case "binary":
|
|
@@ -27,56 +24,7 @@ function serializeRequestBody(req) {
|
|
|
27
24
|
throw new Error(`Invalid serializer mode ${serializerMode}`);
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
|
-
|
|
31
|
-
function serializeBinaryBody(req) {
|
|
32
|
-
const subRequestIds = Object.keys(req.subRequestList), body = {}, executionChain = [];
|
|
33
|
-
for (const id of subRequestIds) {
|
|
34
|
-
let params = req.subRequestList[id].params;
|
|
35
|
-
const method = routesCache.useMethodJitFns(id);
|
|
36
|
-
method.type === HandlerType.headersMiddleFn && method.headersParam && (params = getParamsWithoutHeadersSubset(params)), body[id] = params, executionChain.push(method);
|
|
37
|
-
}
|
|
38
|
-
const workflowRouteIds = req.workflowSubRequests?.map(__assignType((sr) => sr.id, ["sr", "", 'P"2!"/"'])), { buffer } = serializeBinaryBody$1(req.path, executionChain, body, !1, workflowRouteIds);
|
|
39
|
-
return new Uint8Array(buffer);
|
|
40
|
-
}
|
|
41
|
-
serializeBinaryBody.__type = ["MionClientRequest", "req", "serializeBinaryBody", 'P"w!2"W/#'];
|
|
42
|
-
async function deserializeResponseBody(response) {
|
|
43
|
-
const contentType = response.headers.get("content-type"), isJson = contentType?.includes("application/json"), isBinary = contentType?.includes("application/octet-stream");
|
|
44
|
-
let parsedBody;
|
|
45
|
-
if (isJson ? parsedBody = await deserializeJsonResponseBody(response) : isBinary ? parsedBody = await deserializeBinaryResponseBody(response) : parsedBody = await deserializeJsonResponseBody(response), MION_ROUTES.thrownErrors in parsedBody) {
|
|
46
|
-
const unexpectedErrors = parsedBody[MION_ROUTES.thrownErrors];
|
|
47
|
-
if (MION_ROUTES.platformError in unexpectedErrors) {
|
|
48
|
-
const globalErrorValue = unexpectedErrors[MION_ROUTES.platformError], platformError = isRpcError(globalErrorValue) ? new RpcError(globalErrorValue) : globalErrorValue;
|
|
49
|
-
return { [MION_ROUTES.platformError]: platformError };
|
|
50
|
-
}
|
|
51
|
-
Object.assign(parsedBody, unexpectedErrors), delete parsedBody[MION_ROUTES.thrownErrors];
|
|
52
|
-
}
|
|
53
|
-
if (isJson || !isJson && !isBinary) {
|
|
54
|
-
const deserializedBody = {};
|
|
55
|
-
return Object.entries(parsedBody).forEach(__assignType(([methodId, returnValue]) => {
|
|
56
|
-
const method = routesCache.useMethodJitFns(methodId), deserialized = parseHandlerReturnValue(method, returnValue);
|
|
57
|
-
deserializedBody[methodId] = deserialized;
|
|
58
|
-
}, ["param0", "", 'P"2!"/"'])), deserializedBody;
|
|
59
|
-
}
|
|
60
|
-
return parsedBody;
|
|
61
|
-
}
|
|
62
|
-
deserializeResponseBody.__type = ["response", "ResponseBody", "deserializeResponseBody", 'P!2!"w"`/#'];
|
|
63
|
-
async function deserializeJsonResponseBody(response) {
|
|
64
|
-
try {
|
|
65
|
-
return await response.json();
|
|
66
|
-
} catch (err) {
|
|
67
|
-
throw new RpcError({
|
|
68
|
-
type: "parsing-json-response-error",
|
|
69
|
-
publicMessage: `Invalid json response body: ${err?.message || "unknown parsing error."}`
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
deserializeJsonResponseBody.__type = ["response", "deserializeJsonResponseBody", 'P!2!"`/"'];
|
|
74
|
-
async function deserializeBinaryResponseBody(response) {
|
|
75
|
-
const arrayBuffer = await response.arrayBuffer(), { body } = deserializeBinaryBody("client-response", arrayBuffer, !0);
|
|
76
|
-
return body;
|
|
77
|
-
}
|
|
78
|
-
deserializeBinaryResponseBody.__type = ["response", "ResponseBody", "deserializeBinaryResponseBody", 'P!2!"w"`/#'];
|
|
79
|
-
function stringifyBody(req) {
|
|
27
|
+
function serializeJsonBody(req) {
|
|
80
28
|
const props = [], subRequestIds = Object.keys(req.subRequestList);
|
|
81
29
|
for (let i = 0; i < subRequestIds.length; i++) {
|
|
82
30
|
const id = subRequestIds[i], subRequest = req.subRequestList[id];
|
|
@@ -100,19 +48,91 @@ function stringifyBody(req) {
|
|
|
100
48
|
}
|
|
101
49
|
return `{${props.join(",")}}`;
|
|
102
50
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
51
|
+
function serializeJSonBodyOptimistic(req) {
|
|
52
|
+
const body = {}, subRequestIds = Object.keys(req.subRequestList);
|
|
53
|
+
for (const id of subRequestIds) {
|
|
54
|
+
const subRequest = req.subRequestList[id];
|
|
55
|
+
subRequest && (body[id] = subRequest.params);
|
|
56
|
+
}
|
|
57
|
+
return JSON.stringify(body);
|
|
58
|
+
}
|
|
59
|
+
function serializeBinaryBody(req) {
|
|
60
|
+
const subRequestIds = Object.keys(req.subRequestList), body = {}, executionChain = [];
|
|
61
|
+
for (const id of subRequestIds) {
|
|
62
|
+
let params = req.subRequestList[id].params;
|
|
63
|
+
const method = routesCache.useMethodJitFns(id);
|
|
64
|
+
method.type === HandlerType.headersMiddleFn && method.headersParam && (params = getParamsWithoutHeadersSubset(params)), body[id] = params, executionChain.push(method);
|
|
65
|
+
}
|
|
66
|
+
const workflowRouteIds = req.workflowSubRequests?.map((sr) => sr.id), { buffer } = serializeBinaryBody$1(req.path, executionChain, body, !1, workflowRouteIds);
|
|
67
|
+
return new Uint8Array(buffer);
|
|
106
68
|
}
|
|
107
|
-
getParamsWithoutHeadersSubset.__type = ["params", "getParamsWithoutHeadersSubset", 'P"F2!"F/"'];
|
|
108
69
|
function stringifyHandlerParams(method, params) {
|
|
109
70
|
if (!method.paramNames || method.paramNames.length === 0)
|
|
110
71
|
return "";
|
|
111
72
|
const paramsJit = method.paramsJitFns;
|
|
112
73
|
return paramsJit.prepareForJson.isNoop ? JSON.stringify(params) : paramsJit.stringifyJson.fn(params);
|
|
113
74
|
}
|
|
114
|
-
|
|
115
|
-
|
|
75
|
+
async function deserializeResponseBody(response, options) {
|
|
76
|
+
let parsedBody;
|
|
77
|
+
const contentType = response.headers.get("content-type")?.toLowerCase();
|
|
78
|
+
switch (!0) {
|
|
79
|
+
case !!contentType?.includes("application/json"):
|
|
80
|
+
parsedBody = await deserializeJsonResponseBody(response, options);
|
|
81
|
+
break;
|
|
82
|
+
case !!contentType?.includes("application/octet-stream"):
|
|
83
|
+
parsedBody = await deserializeBinaryResponseBody(response);
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
throw new RpcError({
|
|
87
|
+
type: "unsupported-content-type",
|
|
88
|
+
publicMessage: `Unsupported response content-type: '${contentType || "none"}'`
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return parsedBody;
|
|
92
|
+
}
|
|
93
|
+
async function deserializeJsonResponseBody(response, options) {
|
|
94
|
+
try {
|
|
95
|
+
const parsedBody = await response.json();
|
|
96
|
+
extractAndProcessMetadata(MION_ROUTES.methodsMetadata, parsedBody, options), extractAndProcessMetadata(MION_ROUTES.methodsMetadataById, parsedBody, options);
|
|
97
|
+
const platformError = unwrapUnexpectedErrors(parsedBody);
|
|
98
|
+
if (platformError)
|
|
99
|
+
return { [MION_ROUTES.platformError]: platformError };
|
|
100
|
+
const deserializedBody = {};
|
|
101
|
+
return Object.entries(parsedBody).forEach(([methodId, returnValue]) => {
|
|
102
|
+
const method = routesCache.useMethodJitFns(methodId);
|
|
103
|
+
deserializedBody[methodId] = parseHandlerJsonReturnValue(method, returnValue);
|
|
104
|
+
}), deserializedBody;
|
|
105
|
+
} catch (err) {
|
|
106
|
+
throw new RpcError({
|
|
107
|
+
type: "parsing-json-response-error",
|
|
108
|
+
publicMessage: `Invalid json response body: ${err?.message || "unknown parsing error."}`
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function deserializeBinaryResponseBody(response) {
|
|
113
|
+
const arrayBuffer = await response.arrayBuffer(), { body } = deserializeBinaryBody("client-response", arrayBuffer, !0), platformError = unwrapUnexpectedErrors(body);
|
|
114
|
+
return platformError ? { [MION_ROUTES.platformError]: platformError } : body;
|
|
115
|
+
}
|
|
116
|
+
function unwrapUnexpectedErrors(parsedBody) {
|
|
117
|
+
if (!(MION_ROUTES.thrownErrors in parsedBody))
|
|
118
|
+
return;
|
|
119
|
+
const unexpectedErrors = parsedBody[MION_ROUTES.thrownErrors];
|
|
120
|
+
if (MION_ROUTES.platformError in unexpectedErrors) {
|
|
121
|
+
const globalErrorValue = unexpectedErrors[MION_ROUTES.platformError];
|
|
122
|
+
return isRpcError(globalErrorValue) ? new RpcError(globalErrorValue) : globalErrorValue;
|
|
123
|
+
}
|
|
124
|
+
Object.assign(parsedBody, unexpectedErrors), delete parsedBody[MION_ROUTES.thrownErrors];
|
|
125
|
+
}
|
|
126
|
+
function getSerializerMode(req) {
|
|
127
|
+
if (req.options.serializer === "optimistic")
|
|
128
|
+
return Object.keys(req.subRequestList).every((id) => routesCache.hasMetadata(id)) ? "stringifyJson" : "optimistic";
|
|
129
|
+
const methodId = req.route?.id ?? req.workflowSubRequests?.[0]?.id, serializerMode = routesCache.getMethodJitFns(methodId)?.options.serializer || DEFAULT_PREFILL_OPTIONS.serializer;
|
|
130
|
+
return serializerMode === "json" ? DEFAULT_PREFILL_OPTIONS.serializer : serializerMode;
|
|
131
|
+
}
|
|
132
|
+
function getParamsWithoutHeadersSubset(params) {
|
|
133
|
+
return !params || params.length === 0 ? [] : params.slice(1);
|
|
134
|
+
}
|
|
135
|
+
function parseHandlerJsonReturnValue(method, returnValue) {
|
|
116
136
|
if (!method.hasReturnData)
|
|
117
137
|
return returnValue;
|
|
118
138
|
const returnJit = method.returnJitFns;
|
|
@@ -128,11 +148,7 @@ function parseHandlerReturnValue(method, returnValue) {
|
|
|
128
148
|
});
|
|
129
149
|
}
|
|
130
150
|
}
|
|
131
|
-
parseHandlerReturnValue.__type = ["MethodWithJitFns", "method", "returnValue", "parseHandlerReturnValue", 'P"w!2""2#"/$'];
|
|
132
151
|
export {
|
|
133
|
-
__ΩContentType,
|
|
134
|
-
__ΩSerializedBody,
|
|
135
|
-
__ΩSerializedRequest,
|
|
136
152
|
deserializeResponseBody,
|
|
137
153
|
serializeRequestBody
|
|
138
154
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sources":["../../../../src/lib/serializer.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {ResponseBody} from '@mionjs/router';\nimport {\n type MethodWithJitFns,\n RpcError,\n isRpcError,\n routesCache,\n MION_ROUTES,\n HandlerType,\n type SerializerMode,\n serializeBinaryBody as coreSerializeBinaryBody,\n deserializeBinaryBody as coreDeserializeBinaryBody,\n} from '@mionjs/core';\nimport type {MionClientRequest} from '../request.ts';\nimport {DEFAULT_PREFILL_OPTIONS} from '../constants.ts';\nimport {extractAndProcessMetadata} from './clientMethodsMetadata.ts';\nimport {ClientOptions} from '../types.ts';\n\n/** Result of serializing a request body - can be string (JSON) or Uint8Array (binary) */\nexport type SerializedBody = string | Uint8Array;\n\n/** Content-type header value for the serialized body */\nexport type ContentType = 'application/json; charset=utf-8' | 'application/octet-stream';\n\n/** Result of serializing a request body with its content type */\nexport interface SerializedRequest {\n body: SerializedBody;\n contentType: ContentType;\n}\n\n// ################################## SERIALIZE ##################################\n\n/** Serializes the request body and returns it with the appropriate content type */\nexport function serializeRequestBody(req: MionClientRequest<any, any>): SerializedRequest {\n const serializerMode = getSerializerMode(req);\n switch (serializerMode) {\n case 'json':\n case 'stringifyJson':\n return {\n body: serializeJsonBody(req),\n contentType: 'application/json; charset=utf-8',\n };\n case 'optimistic':\n return {\n body: serializeJSonBodyOptimistic(req),\n contentType: 'application/json; charset=utf-8',\n };\n case 'binary':\n return {\n body: serializeBinaryBody(req),\n contentType: 'application/octet-stream',\n };\n default:\n throw new Error(`Invalid serializer mode ${serializerMode}`);\n }\n}\n\nfunction serializeJsonBody(req: MionClientRequest<any, any>): string {\n const props: string[] = [];\n const subRequestIds = Object.keys(req.subRequestList);\n\n for (let i = 0; i < subRequestIds.length; i++) {\n const id = subRequestIds[i];\n const subRequest = req.subRequestList[id];\n if (!subRequest) continue;\n let params = subRequest.params;\n const method = routesCache.useMethodJitFns(id);\n if (method.type === HandlerType.headersMiddleFn && method.headersParam) {\n params = getParamsWithoutHeadersSubset(params);\n }\n try {\n const jsonValue = stringifyHandlerParams(method, params);\n if (!jsonValue) continue;\n props.push(`${JSON.stringify(id)}:${jsonValue}`);\n } catch (e: any) {\n const err = new RpcError({\n type: 'json-stringify-request-error',\n publicMessage: `Failed to stringify params for handler ${id}`,\n originalError: e,\n });\n throw err;\n }\n }\n\n return `{${props.join(',')}}`;\n}\n\n/** Serializes request body as plain JSON without JIT functions */\nfunction serializeJSonBodyOptimistic(req: MionClientRequest<any, any>): string {\n const body: Record<string, any> = {};\n const subRequestIds = Object.keys(req.subRequestList);\n for (const id of subRequestIds) {\n const subRequest = req.subRequestList[id];\n if (!subRequest) continue;\n body[id] = subRequest.params;\n }\n return JSON.stringify(body);\n}\n\n/** Serializes request body to binary format */\nfunction serializeBinaryBody(req: MionClientRequest<any, any>): Uint8Array {\n const subRequestIds = Object.keys(req.subRequestList);\n const body: Record<string, any> = {};\n const executionChain: MethodWithJitFns[] = [];\n\n for (const id of subRequestIds) {\n const subRequest = req.subRequestList[id];\n let params = subRequest.params;\n const method = routesCache.useMethodJitFns(id);\n\n if (method.type === HandlerType.headersMiddleFn && method.headersParam) {\n params = getParamsWithoutHeadersSubset(params);\n }\n\n body[id] = params;\n executionChain.push(method);\n }\n\n const workflowRouteIds = req.workflowSubRequests?.map((sr) => sr.id);\n const {buffer} = coreSerializeBinaryBody(req.path, executionChain, body, false, workflowRouteIds);\n return new Uint8Array(buffer);\n}\n\nfunction stringifyHandlerParams(method: MethodWithJitFns, params: any[]): string {\n if (!method.paramNames || method.paramNames.length === 0) return '';\n const paramsJit = method.paramsJitFns;\n if (paramsJit.prepareForJson.isNoop) return JSON.stringify(params);\n return paramsJit.stringifyJson.fn(params);\n}\n\n// ################################## DE-SERIALIZE ##################################\n\n/** Deserializes the response body from a fetch Response object. Handles routes metadata if present in json responses. */\nexport async function deserializeResponseBody(response: Response, options: ClientOptions): Promise<ResponseBody> {\n let parsedBody: any;\n const contentType = response.headers.get('content-type')?.toLowerCase();\n switch (true) {\n case !!contentType?.includes('application/json'):\n parsedBody = await deserializeJsonResponseBody(response, options);\n break;\n case !!contentType?.includes('application/octet-stream'):\n parsedBody = await deserializeBinaryResponseBody(response);\n break;\n default:\n throw new RpcError({\n type: 'unsupported-content-type',\n publicMessage: `Unsupported response content-type: '${contentType || 'none'}'`,\n });\n }\n return parsedBody;\n}\n\n/** Deserializes JSON response body, Also handles routes metadata if present */\nasync function deserializeJsonResponseBody(response: Response, options: ClientOptions) {\n try {\n const parsedBody = await response.json();\n // Extract & process metadata if present and delete entries after processing (does not use jit functions)\n extractAndProcessMetadata(MION_ROUTES.methodsMetadata, parsedBody, options);\n extractAndProcessMetadata(MION_ROUTES.methodsMetadataById, parsedBody, options);\n // Unwrap unexpected errors (move them from [MION_ROUTES.thrownErrors] to root)\n const platformError = unwrapUnexpectedErrors(parsedBody);\n if (platformError) return {[MION_ROUTES.platformError]: platformError};\n // Deserialize the body using jit functions\n const deserializedBody: ResponseBody = {};\n Object.entries(parsedBody).forEach(([methodId, returnValue]) => {\n const method = routesCache.useMethodJitFns(methodId);\n deserializedBody[methodId] = parseHandlerJsonReturnValue(method, returnValue);\n });\n return deserializedBody;\n } catch (err: any) {\n throw new RpcError({\n type: 'parsing-json-response-error',\n publicMessage: `Invalid json response body: ${err?.message || 'unknown parsing error.'}`,\n });\n }\n}\n\n/** Deserializes binary response body */\nasync function deserializeBinaryResponseBody(response: Response): Promise<ResponseBody> {\n const arrayBuffer = await response.arrayBuffer();\n const {body} = coreDeserializeBinaryBody('client-response', arrayBuffer, true);\n // Unwrap unexpected errors (move them from [MION_ROUTES.thrownErrors] to root)\n const platformError = unwrapUnexpectedErrors(body);\n if (platformError) return {[MION_ROUTES.platformError]: platformError};\n return body;\n}\n\n/** Unwraps unexpected errors from the response body into parsedBody. Returns a platformError if present as a special case. */\nfunction unwrapUnexpectedErrors(parsedBody: any): RpcError<string> | undefined {\n if (!(MION_ROUTES.thrownErrors in parsedBody)) return;\n const unexpectedErrors = parsedBody[MION_ROUTES.thrownErrors];\n // if platform error is present that means the router never executed (just the platform wrapper)\n if (MION_ROUTES.platformError in unexpectedErrors) {\n const globalErrorValue = unexpectedErrors[MION_ROUTES.platformError];\n return isRpcError(globalErrorValue) ? new RpcError<string>(globalErrorValue) : globalErrorValue;\n }\n Object.assign(parsedBody, unexpectedErrors);\n delete parsedBody[MION_ROUTES.thrownErrors];\n}\n\n/** Determines the serializer mode to use for a request */\nfunction getSerializerMode(req: MionClientRequest<any, any>): SerializerMode {\n if (req.options.serializer === 'optimistic') {\n // When metadata is cached (e.g. after retry), use JIT serialization\n const subRequestIds = Object.keys(req.subRequestList);\n const allCached = subRequestIds.every((id) => routesCache.hasMetadata(id));\n if (allCached) return 'stringifyJson';\n return 'optimistic';\n }\n const methodId = req.route?.id ?? req.workflowSubRequests?.[0]?.id;\n const method = routesCache.getMethodJitFns(methodId);\n const serializerMode = method?.options.serializer || DEFAULT_PREFILL_OPTIONS.serializer;\n if (serializerMode === 'json') return DEFAULT_PREFILL_OPTIONS.serializer;\n return serializerMode;\n}\n\n/** Returns params array without the HeadersSubset (first param) */\nfunction getParamsWithoutHeadersSubset(params: any[]): any[] {\n if (!params || params.length === 0) return [];\n return params.slice(1);\n}\n\nfunction parseHandlerJsonReturnValue(method: MethodWithJitFns, returnValue: any): any {\n if (!method.hasReturnData) return returnValue;\n const returnJit = method.returnJitFns;\n if (returnJit.restoreFromJson.isNoop || !returnValue) return returnValue;\n\n try {\n if (returnValue instanceof RpcError) return returnValue;\n if (isRpcError(returnValue)) return new RpcError(returnValue);\n return returnJit.restoreFromJson.fn(returnValue);\n } catch (e: any) {\n return new RpcError({\n type: 'deserialization-error',\n publicMessage: `Invalid response from Route or MiddleFn '${method.id}', can not deserialize return value: ${e.message}`,\n errorData: e?.errors,\n });\n }\n}\n"],"names":["coreSerializeBinaryBody","coreDeserializeBinaryBody"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const STORAGE_GLOBAL_KEY = "__mion_storage__";
|
|
2
2
|
class MemoryStorage {
|
|
3
|
-
data =
|
|
3
|
+
data = /* @__PURE__ */ new Map();
|
|
4
4
|
get length() {
|
|
5
5
|
return this.data.size;
|
|
6
6
|
}
|
|
@@ -19,9 +19,6 @@ class MemoryStorage {
|
|
|
19
19
|
key(index) {
|
|
20
20
|
return [...this.data.keys()][index] ?? null;
|
|
21
21
|
}
|
|
22
|
-
static __type = ["data", function() {
|
|
23
|
-
return Map.Ω = [["&"], ["&"]], /* @__PURE__ */ new Map();
|
|
24
|
-
}, "key", "getItem", "value", "setItem", "removeItem", "clear", "index", "MemoryStorage", `!3!;>"!P&2#P&,J0$P&2#&2%"0&P&2#"0'P"0(P'2)P&,J0#5w*`];
|
|
25
22
|
}
|
|
26
23
|
function getStorage() {
|
|
27
24
|
const existing = globalThis[STORAGE_GLOBAL_KEY];
|
|
@@ -35,11 +32,9 @@ function getStorage() {
|
|
|
35
32
|
}
|
|
36
33
|
return globalThis[STORAGE_GLOBAL_KEY] = storage, storage;
|
|
37
34
|
}
|
|
38
|
-
getStorage.__type = [() => MemoryStorage, "getStorage", 'PP!P7!J/"'];
|
|
39
35
|
function resetStorageInstance() {
|
|
40
36
|
delete globalThis[STORAGE_GLOBAL_KEY];
|
|
41
37
|
}
|
|
42
|
-
resetStorageInstance.__type = ["resetStorageInstance", 'P"/!'];
|
|
43
38
|
export {
|
|
44
39
|
MemoryStorage,
|
|
45
40
|
getStorage,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sources":["../../../../src/lib/storage.ts"],"sourcesContent":["/* ########\n * 2024 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nconst STORAGE_GLOBAL_KEY = '__mion_storage__';\n\n/** In-memory Storage implementation for SSR/Node environments where localStorage is not available */\nexport class MemoryStorage {\n private data = new Map<string, string>();\n get length() {\n return this.data.size;\n }\n getItem(key: string): string | null {\n return this.data.get(key) ?? null;\n }\n setItem(key: string, value: string) {\n this.data.set(key, value);\n }\n removeItem(key: string) {\n this.data.delete(key);\n }\n clear() {\n this.data.clear();\n }\n key(index: number): string | null {\n return [...this.data.keys()][index] ?? null;\n }\n}\n\n/** Returns localStorage if available, otherwise a MemoryStorage instance.\n * Uses globalThis to ensure the same instance is shared across module boundaries. */\nexport function getStorage(): Storage | MemoryStorage {\n const existing = (globalThis as any)[STORAGE_GLOBAL_KEY];\n if (existing) return existing;\n let storage: Storage | MemoryStorage;\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('__mion_test__', '1');\n localStorage.removeItem('__mion_test__');\n storage = localStorage;\n } else {\n storage = new MemoryStorage();\n }\n } catch {\n storage = new MemoryStorage();\n }\n (globalThis as any)[STORAGE_GLOBAL_KEY] = storage;\n return storage;\n}\n\n/** Reset storage instance, useful for testing */\nexport function resetStorageInstance() {\n delete (globalThis as any)[STORAGE_GLOBAL_KEY];\n}\n"],"names":[],"mappings":"AAOA,MAAM,qBAAqB;MAGd,cAAa;AAAA,EACd,2BAAW,IAAA;AAAA,EACnB,IAAI,SAAM;AACN,WAAO,KAAK,KAAK;AAAA,EACrB;AAAA,EACA,QAAQ,KAAW;AACf,WAAO,KAAK,KAAK,IAAI,GAAG,KAAK;AAAA,EACjC;AAAA,EACA,QAAQ,KAAa,OAAa;AAC9B,SAAK,KAAK,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA,EACA,WAAW,KAAW;AAClB,SAAK,KAAK,OAAO,GAAG;AAAA,EACxB;AAAA,EACA,QAAK;AACD,SAAK,KAAK,MAAA;AAAA,EACd;AAAA,EACA,IAAI,OAAa;AACb,WAAO,CAAC,GAAG,KAAK,KAAK,MAAM,EAAE,KAAK,KAAK;AAAA,EAC3C;AACH;SAIe,aAAU;AACtB,QAAM,WAAY,WAAmB,kBAAkB;AACvD,MAAI;AAAU,WAAO;AACrB,MAAI;AACJ,MAAI;AACA,IAAI,OAAO,eAAiB,OACxB,aAAa,QAAQ,iBAAiB,GAAG,GACzC,aAAa,WAAW,eAAe,GACvC,UAAU,gBAEV,UAAU,IAAI,cAAA;AAAA,EAEtB,QAAQ;AACJ,cAAU,IAAI,cAAA;AAAA,EAClB;AACC,oBAAmB,kBAAkB,IAAI,SACnC;AACX;SAGgB,uBAAoB;AAChC,SAAQ,WAAmB,kBAAkB;AACjD;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { routesCache, resetJitFnCaches, resetJitFunctionsCache } from "@mionjs/core";
|
|
2
|
+
function resetClientCaches() {
|
|
3
|
+
const cache = routesCache.getCache();
|
|
4
|
+
for (const key in cache)
|
|
5
|
+
delete cache[key];
|
|
6
|
+
resetJitFnCaches(), resetJitFunctionsCache();
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
resetClientCaches
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=testUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testUtils.js","sources":["../../../../src/lib/testUtils.ts"],"sourcesContent":["/* ########\n * 2024 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {resetJitFnCaches, resetJitFunctionsCache, routesCache} from '@mionjs/core';\n\n/** Resets all client caches. Only for testing — simulates app restart. */\nexport function resetClientCaches() {\n const cache = routesCache.getCache();\n for (const key in cache) delete cache[key];\n resetJitFnCaches();\n resetJitFunctionsCache();\n}\n"],"names":[],"mappings":";SAUgB,oBAAiB;AAC7B,QAAM,QAAQ,YAAY,SAAA;AAC1B,aAAW,OAAO;AAAO,WAAO,MAAM,GAAG;AACzC,mBAAA,GACA,uBAAA;AACJ;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RpcError } from '@mionjs/core';
|
|
2
2
|
import { HandlersRegistry } from './handlersRegistry.ts';
|
|
3
|
-
import { SuccessHandler } from '
|
|
3
|
+
import { SuccessHandler } from '../types.ts';
|
|
4
4
|
export declare class TypedEvent<S = void, E extends RpcError<string, any> = never> {
|
|
5
5
|
private readonly handlerId;
|
|
6
6
|
private readonly registry;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const __ΩExtract = ["T", "U", "Extract", `l6e$!R!RPe#!e$"qk#'QRb!b"Pde"!p)w#y`];
|
|
2
1
|
class TypedEvent {
|
|
3
2
|
handlerId;
|
|
4
3
|
registry;
|
|
@@ -33,7 +32,6 @@ class TypedEvent {
|
|
|
33
32
|
hasSuccessHandler() {
|
|
34
33
|
return this.registry.hasSuccessHandler(this.handlerId);
|
|
35
34
|
}
|
|
36
|
-
static __type = ["S", "E", "handlerId", "HandlersRegistry", "registry", "constructor", "SuccessHandler", "handler", () => TypedEvent, "onSuccess", () => TypedEvent, "offSuccess", "errorType", () => __ΩExtract, "type", "error", "", () => TypedEvent, "onError", () => TypedEvent, "offError", "getHandlerId", "hasErrorHandler", "hasSuccessHandler", "TypedEvent", `$c!!c"P&2#;9"w$2%;9"0&P"w'2(Pe#!e#"7)0*PPe#!e#"7+0,P"2-Pe#"P"4/Mo.#20$/12(Pe#!e#"7203P"2-Pe#!e#"7405P&06P&2-)07P)085w9`];
|
|
37
35
|
}
|
|
38
36
|
export {
|
|
39
37
|
TypedEvent
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typedEvent.js","sources":["../../../../src/lib/typedEvent.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {RpcError} from '@mionjs/core';\nimport type {HandlersRegistry} from './handlersRegistry.ts';\nimport type {ErrorHandler, SuccessHandler} from '../types.ts';\n\n/** Persistent event emitter for middleFn success and error handling */\nexport class TypedEvent<S = void, E extends RpcError<string, any> = never> {\n constructor(\n private readonly handlerId: string,\n private readonly registry: HandlersRegistry\n ) {}\n\n /** Register a persistent success handler for this middleFn */\n onSuccess(handler: SuccessHandler<S>): TypedEvent<S, E> {\n this.registry.registerSuccess(this.handlerId, handler);\n return this;\n }\n\n /** Remove a previously registered success handler from HandlersRegistry */\n offSuccess(): TypedEvent<S, E> {\n this.registry.unregisterSuccess(this.handlerId);\n return this;\n }\n\n /** Register a persistent error handler for this middleFn */\n onError<T extends E['type']>(errorType: T, handler: (error: Extract<E, {type: T}>) => void): TypedEvent<S, E> {\n this.registry.register(this.handlerId, errorType, handler as ErrorHandler<any>);\n return this;\n }\n\n /** Remove a previously registered error handler from HandlersRegistry */\n offError<T extends E['type']>(errorType: T): TypedEvent<S, E> {\n this.registry.unregister(this.handlerId, errorType);\n return this;\n }\n\n /** Get the handler ID this event is associated with */\n getHandlerId(): string {\n return this.handlerId;\n }\n\n /** Check if an error handler is registered for a specific error type */\n hasErrorHandler(errorType: string): boolean {\n return this.registry.hasHandler(this.handlerId, errorType);\n }\n\n /** Check if a success handler is registered */\n hasSuccessHandler(): boolean {\n return this.registry.hasSuccessHandler(this.handlerId);\n }\n}\n"],"names":[],"mappings":"MAYa,WAAU;AAAA,EAEE;AAAA,EACA;AAAA,EAFrB,YACqB,WACA,UAA0B;AAD1B,SAAA,YAAA,WACA,KAAA,WAAA;AAAA,EAClB;AAAA;AAAA,EAGH,UAAU,SAA0B;AAChC,gBAAK,SAAS,gBAAgB,KAAK,WAAW,OAAO,GAC9C;AAAA,EACX;AAAA;AAAA,EAGA,aAAU;AACN,gBAAK,SAAS,kBAAkB,KAAK,SAAS,GACvC;AAAA,EACX;AAAA;AAAA,EAGA,QAA6B,WAAc,SAA+C;AACtF,gBAAK,SAAS,SAAS,KAAK,WAAW,WAAW,OAA4B,GACvE;AAAA,EACX;AAAA;AAAA,EAGA,SAA8B,WAAY;AACtC,gBAAK,SAAS,WAAW,KAAK,WAAW,SAAS,GAC3C;AAAA,EACX;AAAA;AAAA,EAGA,eAAY;AACR,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA,EAGA,gBAAgB,WAAiB;AAC7B,WAAO,KAAK,SAAS,WAAW,KAAK,WAAW,SAAS;AAAA,EAC7D;AAAA;AAAA,EAGA,oBAAiB;AACb,WAAO,KAAK,SAAS,kBAAkB,KAAK,SAAS;AAAA,EACzD;AACH;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestErrors, SubRequest } from '
|
|
2
|
-
import { MionClientRequest } from '
|
|
1
|
+
import { RequestErrors, SubRequest } from '../types.ts';
|
|
2
|
+
import { MionClientRequest } from '../request.ts';
|
|
3
3
|
export declare function validateSubRequests(subRequestIds: string[], req: MionClientRequest<any, any>, errors: RequestErrors, validateRouteMiddleFns?: boolean): void;
|
|
4
4
|
export declare function validateSubRequest(id: string, subRequest: SubRequest<any>, errors: RequestErrors): void;
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { routesCache, RpcError } from "@mionjs/core";
|
|
2
|
-
import { __ΩRequestErrors as ___RequestErrors, __ΩSubRequest as ___SubRequest } from "./types.js";
|
|
3
|
-
function __assignType(fn, args) {
|
|
4
|
-
return fn.__type = args, fn;
|
|
5
|
-
}
|
|
6
2
|
function validateSubRequests(subRequestIds, req, errors, validateRouteMiddleFns = !0) {
|
|
7
|
-
req.options.validateParams && subRequestIds.forEach(
|
|
3
|
+
req.options.validateParams && subRequestIds.forEach((id) => {
|
|
8
4
|
const subRequest = req.subRequestList[id];
|
|
9
5
|
validateSubRequest(id, subRequest, errors);
|
|
10
6
|
const methodMeta = routesCache.getMetadata(id);
|
|
11
7
|
if (validateRouteMiddleFns && methodMeta?.middleFnIds?.length) {
|
|
12
|
-
const validMiddleFnIds = methodMeta.middleFnIds.filter(
|
|
8
|
+
const validMiddleFnIds = methodMeta.middleFnIds.filter((middleFnId) => middleFnId != null);
|
|
13
9
|
validateSubRequests(validMiddleFnIds, req, errors, validateRouteMiddleFns);
|
|
14
10
|
}
|
|
15
|
-
}
|
|
11
|
+
});
|
|
16
12
|
}
|
|
17
|
-
validateSubRequests.__type = ["subRequestIds", "MionClientRequest", "req", () => ___RequestErrors, "errors", "validateRouteMiddleFns", "validateSubRequests", `P&F2!"w"2#n$2%"2&$/'`];
|
|
18
13
|
function validateSubRequest(id, subRequest, errors) {
|
|
19
14
|
if (subRequest?.error || subRequest?.isResolved)
|
|
20
15
|
return;
|
|
@@ -27,7 +22,6 @@ function validateSubRequest(id, subRequest, errors) {
|
|
|
27
22
|
const error = validationResponse;
|
|
28
23
|
errors.set(id, error), subRequest && (subRequest.error = error, subRequest.isResolved = !0);
|
|
29
24
|
}
|
|
30
|
-
validateSubRequest.__type = ["id", () => ___SubRequest, "subRequest", () => ___RequestErrors, "errors", "validateSubRequest", 'P&2!"o""2#n$2%$/&'];
|
|
31
25
|
function getTypeErrors(id, params) {
|
|
32
26
|
const method = routesCache.useMethodJitFns(id);
|
|
33
27
|
if (!method.paramNames || method.paramNames.length === 0)
|
|
@@ -49,7 +43,6 @@ function getTypeErrors(id, params) {
|
|
|
49
43
|
});
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
|
-
getTypeErrors.__type = ["id", "params", "validation-error", "unexpected-validation-error", () => RpcError, "getTypeErrors", 'P&2!"F2"P$PP.#.$J7%J/&'];
|
|
53
46
|
export {
|
|
54
47
|
validateSubRequest,
|
|
55
48
|
validateSubRequests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sources":["../../../../src/lib/validation.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, routesCache} from '@mionjs/core';\nimport {RequestErrors, SubRequest} from '../types.ts';\nimport type {MionClientRequest} from '../request.ts';\n\n/** Validate subRequests locally using existing RemoteApi metadata */\nexport function validateSubRequests(\n subRequestIds: string[],\n req: MionClientRequest<any, any>,\n errors: RequestErrors,\n validateRouteMiddleFns = true\n): void {\n if (!req.options.validateParams) return;\n subRequestIds.forEach((id) => {\n const subRequest = req.subRequestList[id];\n validateSubRequest(id, subRequest, errors);\n const methodMeta = routesCache.getMetadata(id);\n if (validateRouteMiddleFns && methodMeta?.middleFnIds?.length) {\n const validMiddleFnIds = methodMeta.middleFnIds.filter((middleFnId) => middleFnId != null);\n validateSubRequests(validMiddleFnIds, req, errors, validateRouteMiddleFns);\n }\n });\n return;\n}\n\n/** Validate subRequest locally using existing RemoteApi metadata */\nexport function validateSubRequest(id: string, subRequest: SubRequest<any>, errors: RequestErrors): void {\n if (subRequest?.error || subRequest?.isResolved) return;\n // Skip validation for subrequests with mapFrom mappings — params contain null placeholders\n // that will be filled by the server's mapping step after the source route executes\n const mappings = (subRequest as any)?.mappings;\n if (Array.isArray(mappings) && mappings.length > 0) return;\n\n const params = subRequest?.params || [];\n const validationResponse = getTypeErrors(id, params);\n if (!validationResponse) return;\n const error = validationResponse;\n errors.set(id, error);\n if (subRequest) {\n subRequest.error = error;\n subRequest.isResolved = true;\n }\n return;\n}\n\nfunction getTypeErrors(id: string, params: any[]): void | RpcError<'validation-error' | 'unexpected-validation-error'> {\n const method = routesCache.useMethodJitFns(id);\n if (!method.paramNames || method.paramNames.length === 0) return;\n const paramsJit = method.paramsJitFns;\n if (paramsJit.typeErrors.isNoop) return;\n try {\n const validationsResponse = paramsJit.isType.fn(params) || paramsJit.typeErrors.fn(params);\n if ((validationsResponse as [])?.length) {\n return new RpcError({\n type: 'validation-error',\n publicMessage: `Invalid params for Route or MiddleFn '${method.id}', validation failed.`,\n errorData: validationsResponse,\n });\n }\n } catch (e: any | Error) {\n return new RpcError({\n type: 'unexpected-validation-error',\n publicMessage: `Could not validate params for Route or MiddleFn '${method.id}': ${e.message} `,\n });\n }\n}\n"],"names":[],"mappings":";AAYM,SAAU,oBACZ,eACA,KACA,QACA,yBAAyB,IAAI;AAE7B,EAAK,IAAI,QAAQ,kBACjB,cAAc,QAAQ,CAAC,OAAM;AACzB,UAAM,aAAa,IAAI,eAAe,EAAE;AACxC,uBAAmB,IAAI,YAAY,MAAM;AACzC,UAAM,aAAa,YAAY,YAAY,EAAE;AAC7C,QAAI,0BAA0B,YAAY,aAAa,QAAQ;AAC3D,YAAM,mBAAmB,WAAW,YAAY,OAAO,CAAC,eAAe,cAAc,IAAI;AACzF,0BAAoB,kBAAkB,KAAK,QAAQ,sBAAsB;AAAA,IAC7E;AAAA,EACJ,CAAC;AAEL;SAGgB,mBAAmB,IAAY,YAA6B,QAAqB;AAC7F,MAAI,YAAY,SAAS,YAAY;AAAY;AAGjD,QAAM,WAAY,YAAoB;AACtC,MAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS;AAAG;AAEpD,QAAM,SAAS,YAAY,UAAU,CAAA,GAC/B,qBAAqB,cAAc,IAAI,MAAM;AACnD,MAAI,CAAC;AAAoB;AACzB,QAAM,QAAQ;AACd,SAAO,IAAI,IAAI,KAAK,GAChB,eACA,WAAW,QAAQ,OACnB,WAAW,aAAa;AAGhC;AAEA,SAAS,cAAc,IAAY,QAAa;AAC5C,QAAM,SAAS,YAAY,gBAAgB,EAAE;AAC7C,MAAI,CAAC,OAAO,cAAc,OAAO,WAAW,WAAW;AAAG;AAC1D,QAAM,YAAY,OAAO;AACzB,MAAI,WAAU,WAAW;AACzB,QAAI;AACA,YAAM,sBAAsB,UAAU,OAAO,GAAG,MAAM,KAAK,UAAU,WAAW,GAAG,MAAM;AACzF,UAAK,qBAA4B;AAC7B,eAAO,IAAI,SAAS;AAAA,UAChB,MAAM;AAAA,UACN,eAAe,yCAAyC,OAAO,EAAE;AAAA,UACjE,WAAW;AAAA,QAAA,CACd;AAAA,IAET,SAAS,GAAgB;AACrB,aAAO,IAAI,SAAS;AAAA,QAChB,MAAM;AAAA,QACN,eAAe,oDAAoD,OAAO,EAAE,MAAM,EAAE,OAAO;AAAA,MAAA,CAC9F;AAAA,IACL;AACJ;"}
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import { ResponseBody } from '@mionjs/router';
|
|
2
|
-
import { ClientOptions,
|
|
2
|
+
import { ClientOptions, MiddlewareSubRequest, SubRequest, RouteSubRequest, PrefilledMiddleFnsCache } from './types.ts';
|
|
3
3
|
import { RunTypeError } from '@mionjs/core';
|
|
4
|
-
export declare class MionClientRequest<RR extends
|
|
4
|
+
export declare class MionClientRequest<RR extends RouteSubRequest<any>, MiddleFnRequestsList extends MiddlewareSubRequest<any>[]> {
|
|
5
5
|
readonly options: ClientOptions;
|
|
6
6
|
private readonly prefilledMiddleFnsCache;
|
|
7
7
|
readonly route?: RR | undefined;
|
|
8
8
|
readonly middleFns?: MiddleFnRequestsList | undefined;
|
|
9
|
-
readonly workflowSubRequests?:
|
|
9
|
+
readonly workflowSubRequests?: RouteSubRequest<any>[] | undefined;
|
|
10
|
+
readonly signal?: AbortSignal | undefined;
|
|
10
11
|
readonly path: string;
|
|
11
12
|
readonly requestId: string;
|
|
12
13
|
readonly subRequestList: {
|
|
13
14
|
[key: string]: SubRequest<any>;
|
|
14
15
|
};
|
|
15
16
|
response: Response | undefined;
|
|
16
|
-
constructor(options: ClientOptions, prefilledMiddleFnsCache: PrefilledMiddleFnsCache, route?: RR | undefined, middleFns?: MiddleFnRequestsList | undefined, workflowSubRequests?:
|
|
17
|
+
constructor(options: ClientOptions, prefilledMiddleFnsCache: PrefilledMiddleFnsCache, route?: RR | undefined, middleFns?: MiddleFnRequestsList | undefined, workflowSubRequests?: RouteSubRequest<any>[] | undefined, signal?: AbortSignal | undefined);
|
|
17
18
|
call(): Promise<ResponseBody>;
|
|
19
|
+
private makeCall;
|
|
20
|
+
private shouldRetryWithProperSerialization;
|
|
21
|
+
private retryWithProperSerialization;
|
|
18
22
|
validateParams(subReqList?: SubRequest<any>[]): Promise<RunTypeError[]>;
|
|
19
23
|
prefill(subReqList?: SubRequest<any>[]): Promise<void>;
|
|
20
24
|
removePrefill(subRequests?: SubRequest<any>[]): Promise<void>;
|
|
21
25
|
addSubRequest(subRequest: SubRequest<any>): void;
|
|
26
|
+
private handlePlatformError;
|
|
27
|
+
private resolveSubRequests;
|
|
22
28
|
private onError;
|
|
23
29
|
private getResponseValueFromBodyOrHeader;
|
|
24
30
|
private restorePrefilledMiddleFns;
|