@schmock/core 2.3.0 → 2.4.0
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/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/abort.d.ts +3 -0
- package/dist/abort.d.ts.map +1 -0
- package/dist/abort.js +30 -0
- package/dist/builder.d.ts +31 -10
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +760 -190
- package/dist/constants.d.ts +38 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +123 -2
- package/dist/errors.d.ts +14 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +41 -6
- package/dist/helpers.d.ts +9 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +18 -2
- package/dist/http-helpers.d.ts +39 -4
- package/dist/http-helpers.d.ts.map +1 -1
- package/dist/http-helpers.js +147 -49
- package/dist/index.d.ts +292 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/interceptor.d.ts +11 -1
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +316 -169
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +12 -3
- package/dist/plugin-pipeline.d.ts +3 -3
- package/dist/plugin-pipeline.d.ts.map +1 -1
- package/dist/plugin-pipeline.js +29 -14
- package/dist/response-normalizer.d.ts +16 -0
- package/dist/response-normalizer.d.ts.map +1 -0
- package/dist/response-normalizer.js +316 -0
- package/dist/response-parser.d.ts.map +1 -1
- package/dist/response-parser.js +39 -2
- package/dist/route-matcher.d.ts +3 -0
- package/dist/route-matcher.d.ts.map +1 -1
- package/dist/route-matcher.js +12 -6
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +18 -6
- package/src/audit-core-builder.test.ts +0 -218
- package/src/audit-response-guard.test.ts +0 -38
- package/src/binary.test.ts +0 -126
- package/src/binary.ts +0 -11
- package/src/builder.test.ts +0 -289
- package/src/builder.ts +0 -748
- package/src/constants.test.ts +0 -99
- package/src/constants.ts +0 -73
- package/src/debug.test.ts +0 -241
- package/src/delay.test.ts +0 -319
- package/src/dist-shape.test.ts +0 -35
- package/src/errors.test.ts +0 -223
- package/src/errors.ts +0 -130
- package/src/factory.test.ts +0 -133
- package/src/helpers.test.ts +0 -147
- package/src/helpers.ts +0 -58
- package/src/http-helpers.test.ts +0 -39
- package/src/http-helpers.ts +0 -149
- package/src/index.ts +0 -152
- package/src/interceptor.test.ts +0 -488
- package/src/interceptor.ts +0 -407
- package/src/namespace.test.ts +0 -274
- package/src/parser.property.test.ts +0 -630
- package/src/parser.test.ts +0 -148
- package/src/parser.ts +0 -64
- package/src/plugin-pipeline.ts +0 -208
- package/src/plugin-system.test.ts +0 -697
- package/src/response-parser.ts +0 -114
- package/src/response-parsing.test.ts +0 -333
- package/src/route-matcher.ts +0 -69
- package/src/route-matching.test.ts +0 -394
- package/src/server.test.ts +0 -234
- package/src/smart-defaults.test.ts +0 -361
- package/src/steps/async-support.steps.ts +0 -421
- package/src/steps/audit-core-builder.steps.ts +0 -188
- package/src/steps/audit-onerror-tuple.steps.ts +0 -83
- package/src/steps/basic-usage.steps.ts +0 -245
- package/src/steps/developer-experience.steps.ts +0 -204
- package/src/steps/error-handling.steps.ts +0 -555
- package/src/steps/fetch-interceptor.steps.ts +0 -457
- package/src/steps/fluent-api.steps.ts +0 -255
- package/src/steps/http-methods.steps.ts +0 -342
- package/src/steps/lifecycle-events.steps.ts +0 -149
- package/src/steps/performance-reliability.steps.ts +0 -90
- package/src/steps/plugin-integration.steps.ts +0 -334
- package/src/steps/request-history.steps.ts +0 -458
- package/src/steps/response-delay.steps.ts +0 -88
- package/src/steps/route-key-format.steps.ts +0 -99
- package/src/steps/standalone-server.steps.ts +0 -227
- package/src/steps/state-concurrency.steps.ts +0 -167
- package/src/types.ts +0 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-pipeline.d.ts","sourceRoot":"","sources":["../src/plugin-pipeline.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin-pipeline.d.ts","sourceRoot":"","sources":["../src/plugin-pipeline.ts"],"names":[],"mappings":"AAGA,uEAAuE;AACvE,UAAU,cAAc;IACtB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9D;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAmED,kEAAkE;AAClE,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,SAAS,OAAO,CAAC,MAAM,EAAE,EAClC,OAAO,EAAE,OAAO,CAAC,aAAa,EAC9B,MAAM,EAAE,cAAc,EACtB,MAAM,0BAAiB,GACtB,OAAO,CAAC,cAAc,CAAC,CAwDzB;AAED,gFAAgF;AAChF,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,SAAS,OAAO,CAAC,MAAM,EAAE,EAClC,OAAO,EAAE,OAAO,CAAC,aAAa,EAC9B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,cAAc,EACtB,MAAM,0BAAiB,GACtB,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,SAAS,OAAO,CAAC,MAAM,EAAE,EAClC,OAAO,EAAE,OAAO,CAAC,aAAa,EAC9B,eAAe,EAAE,OAAO,EACxB,MAAM,EAAE,cAAc,EACtB,MAAM,0BAAiB,GACtB,OAAO,CAAC,cAAc,CAAC,CAiEzB"}
|
package/dist/plugin-pipeline.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { awaitWithAbort, throwIfAborted } from "./abort.js";
|
|
1
2
|
import { errorMessage, PluginError } from "./errors.js";
|
|
2
3
|
function isPluginResult(value) {
|
|
3
4
|
return (typeof value === "object" &&
|
|
@@ -6,14 +7,19 @@ function isPluginResult(value) {
|
|
|
6
7
|
typeof value.context === "object" &&
|
|
7
8
|
value.context !== null);
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
function preserveRequestSignal(context, signal) {
|
|
11
|
+
return context.signal === signal ? context : { ...context, signal };
|
|
12
|
+
}
|
|
13
|
+
async function recoverPluginError(plugins, startIndex, error, context, logger, signal) {
|
|
10
14
|
let currentError = error instanceof Error ? error : new Error(errorMessage(error));
|
|
11
15
|
for (let index = startIndex; index < plugins.length; index += 1) {
|
|
16
|
+
throwIfAborted(signal);
|
|
12
17
|
const plugin = plugins[index];
|
|
13
18
|
if (!plugin.onError)
|
|
14
19
|
continue;
|
|
15
20
|
try {
|
|
16
|
-
const errorResult = await plugin.onError(currentError, context);
|
|
21
|
+
const errorResult = await awaitWithAbort(plugin.onError(currentError, context), signal);
|
|
22
|
+
throwIfAborted(signal);
|
|
17
23
|
if (errorResult instanceof Error) {
|
|
18
24
|
currentError = errorResult;
|
|
19
25
|
continue;
|
|
@@ -24,6 +30,7 @@ async function recoverPluginError(plugins, startIndex, error, context, logger) {
|
|
|
24
30
|
}
|
|
25
31
|
}
|
|
26
32
|
catch (hookError) {
|
|
33
|
+
throwIfAborted(signal);
|
|
27
34
|
currentError =
|
|
28
35
|
hookError instanceof Error
|
|
29
36
|
? hookError
|
|
@@ -34,21 +41,23 @@ async function recoverPluginError(plugins, startIndex, error, context, logger) {
|
|
|
34
41
|
return { handled: false, error: currentError };
|
|
35
42
|
}
|
|
36
43
|
/** Run request guards before route code is allowed to execute. */
|
|
37
|
-
export async function runPluginBeforeRequest(plugins, context, logger) {
|
|
38
|
-
let currentContext = context;
|
|
44
|
+
export async function runPluginBeforeRequest(plugins, context, logger, signal = context.signal) {
|
|
45
|
+
let currentContext = preserveRequestSignal(context, signal);
|
|
39
46
|
for (let index = 0; index < plugins.length; index += 1) {
|
|
47
|
+
throwIfAborted(signal);
|
|
40
48
|
const plugin = plugins[index];
|
|
41
49
|
if (!plugin.beforeRequest)
|
|
42
50
|
continue;
|
|
43
51
|
logger.log("pipeline", `Running beforeRequest: ${plugin.name}`);
|
|
44
52
|
try {
|
|
45
|
-
const result = await plugin.beforeRequest(currentContext);
|
|
53
|
+
const result = await awaitWithAbort(plugin.beforeRequest(currentContext), signal);
|
|
54
|
+
throwIfAborted(signal);
|
|
46
55
|
if (result === undefined)
|
|
47
56
|
continue;
|
|
48
57
|
if (!isPluginResult(result)) {
|
|
49
58
|
throw new Error(`Plugin ${plugin.name} didn't return valid result`);
|
|
50
59
|
}
|
|
51
|
-
currentContext = result.context;
|
|
60
|
+
currentContext = preserveRequestSignal(result.context, signal);
|
|
52
61
|
if (result.response !== undefined) {
|
|
53
62
|
logger.log("pipeline", `Plugin ${plugin.name} rejected request`);
|
|
54
63
|
return {
|
|
@@ -59,8 +68,9 @@ export async function runPluginBeforeRequest(plugins, context, logger) {
|
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
catch (error) {
|
|
71
|
+
throwIfAborted(signal);
|
|
62
72
|
logger.log("pipeline", `Plugin ${plugin.name} beforeRequest failed: ${errorMessage(error)}`);
|
|
63
|
-
const recovery = await recoverPluginError(plugins, index, error, currentContext, logger);
|
|
73
|
+
const recovery = await recoverPluginError(plugins, index, error, currentContext, logger, signal);
|
|
64
74
|
if (recovery.handled) {
|
|
65
75
|
return {
|
|
66
76
|
context: currentContext,
|
|
@@ -75,8 +85,10 @@ export async function runPluginBeforeRequest(plugins, context, logger) {
|
|
|
75
85
|
return { context: currentContext };
|
|
76
86
|
}
|
|
77
87
|
/** Give pipeline error handlers a chance to recover a route-generator error. */
|
|
78
|
-
export async function recoverGeneratorError(plugins, context, error, logger) {
|
|
79
|
-
|
|
88
|
+
export async function recoverGeneratorError(plugins, context, error, logger, signal = context.signal) {
|
|
89
|
+
throwIfAborted(signal);
|
|
90
|
+
const recovery = await recoverPluginError(plugins, 0, error, context, logger, signal);
|
|
91
|
+
throwIfAborted(signal);
|
|
80
92
|
if (recovery.handled) {
|
|
81
93
|
return {
|
|
82
94
|
context,
|
|
@@ -91,19 +103,21 @@ export async function recoverGeneratorError(plugins, context, error, logger) {
|
|
|
91
103
|
* First plugin to set response becomes generator, subsequent plugins transform
|
|
92
104
|
* Handles plugin errors via onError hooks
|
|
93
105
|
*/
|
|
94
|
-
export async function runPluginPipeline(plugins, context, initialResponse, logger) {
|
|
95
|
-
let currentContext = context;
|
|
106
|
+
export async function runPluginPipeline(plugins, context, initialResponse, logger, signal = context.signal) {
|
|
107
|
+
let currentContext = preserveRequestSignal(context, signal);
|
|
96
108
|
let response = initialResponse;
|
|
97
109
|
logger.log("pipeline", `Running plugin pipeline for ${plugins.length} plugins`);
|
|
98
110
|
for (let index = 0; index < plugins.length; index += 1) {
|
|
111
|
+
throwIfAborted(signal);
|
|
99
112
|
const plugin = plugins[index];
|
|
100
113
|
logger.log("pipeline", `Processing plugin: ${plugin.name}`);
|
|
101
114
|
try {
|
|
102
|
-
const result = await plugin.process(currentContext, response);
|
|
115
|
+
const result = await awaitWithAbort(plugin.process(currentContext, response), signal);
|
|
116
|
+
throwIfAborted(signal);
|
|
103
117
|
if (!isPluginResult(result)) {
|
|
104
118
|
throw new Error(`Plugin ${plugin.name} didn't return valid result`);
|
|
105
119
|
}
|
|
106
|
-
currentContext = result.context;
|
|
120
|
+
currentContext = preserveRequestSignal(result.context, signal);
|
|
107
121
|
// First plugin to set response becomes the generator
|
|
108
122
|
if (result.response !== undefined &&
|
|
109
123
|
(response === undefined || response === null)) {
|
|
@@ -116,8 +130,9 @@ export async function runPluginPipeline(plugins, context, initialResponse, logge
|
|
|
116
130
|
}
|
|
117
131
|
}
|
|
118
132
|
catch (error) {
|
|
133
|
+
throwIfAborted(signal);
|
|
119
134
|
logger.log("pipeline", `Plugin ${plugin.name} failed: ${errorMessage(error)}`);
|
|
120
|
-
const recovery = await recoverPluginError(plugins, index, error, currentContext, logger);
|
|
135
|
+
const recovery = await recoverPluginError(plugins, index, error, currentContext, logger, signal);
|
|
121
136
|
if (recovery.handled) {
|
|
122
137
|
return {
|
|
123
138
|
context: currentContext,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type OwnedBytes = ReturnType<typeof Uint8Array.of>;
|
|
2
|
+
interface NormalizableResponse {
|
|
3
|
+
status: number;
|
|
4
|
+
body: unknown;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Validate and stabilize a response before it reaches a transport adapter.
|
|
9
|
+
*/
|
|
10
|
+
export declare function normalizeResponse(response: NormalizableResponse, method: string): Schmock.Response;
|
|
11
|
+
/**
|
|
12
|
+
* Encode a response body using its normalized content type semantics.
|
|
13
|
+
*/
|
|
14
|
+
export declare function serializeResponseBody(response: Schmock.Response): OwnedBytes | undefined;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=response-normalizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-normalizer.d.ts","sourceRoot":"","sources":["../src/response-normalizer.ts"],"names":[],"mappings":"AAwBA,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;AAEnD,UAAU,oBAAoB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAmSD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,CAmClB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ,GACzB,UAAU,GAAG,SAAS,CAcxB"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { isBinaryBody } from "./binary.js";
|
|
2
|
+
import { errorMessage, InvalidResponseError } from "./errors.js";
|
|
3
|
+
const BODY_FORBIDDEN_STATUSES = new Set([204, 205, 304]);
|
|
4
|
+
const HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
5
|
+
const FRAMING_HEADERS = new Set([
|
|
6
|
+
"content-length",
|
|
7
|
+
"trailer",
|
|
8
|
+
"transfer-encoding",
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Headers that describe the connection rather than the message (RFC 9110 §7.6.1).
|
|
12
|
+
* Kept separate from {@link FRAMING_HEADERS}, which is parameterised by
|
|
13
|
+
* `preserveContentLength`: these are never a route's to send, so the strip is
|
|
14
|
+
* unconditional.
|
|
15
|
+
*/
|
|
16
|
+
const HOP_BY_HOP_HEADERS = new Set([
|
|
17
|
+
"connection",
|
|
18
|
+
"keep-alive",
|
|
19
|
+
"proxy-authenticate",
|
|
20
|
+
"proxy-authorization",
|
|
21
|
+
"te",
|
|
22
|
+
"upgrade",
|
|
23
|
+
]);
|
|
24
|
+
function hasInvalidHeaderValue(value) {
|
|
25
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
26
|
+
const code = value.charCodeAt(index);
|
|
27
|
+
if (code <= 8 || (code >= 10 && code <= 31) || code === 127)
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
function validateStatus(status) {
|
|
33
|
+
if (typeof status !== "number" ||
|
|
34
|
+
!Number.isFinite(status) ||
|
|
35
|
+
!Number.isInteger(status) ||
|
|
36
|
+
status < 200 ||
|
|
37
|
+
status > 599) {
|
|
38
|
+
throw new InvalidResponseError("status must be a finite integer from 200 through 599", { status });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function headerEntries(headers) {
|
|
42
|
+
if (typeof headers !== "object" ||
|
|
43
|
+
headers === null ||
|
|
44
|
+
Array.isArray(headers)) {
|
|
45
|
+
throw new InvalidResponseError("headers must be a string record");
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const entries = [];
|
|
49
|
+
for (const name of Reflect.ownKeys(headers)) {
|
|
50
|
+
const descriptor = Object.getOwnPropertyDescriptor(headers, name);
|
|
51
|
+
if (!descriptor?.enumerable)
|
|
52
|
+
continue;
|
|
53
|
+
if (typeof name !== "string") {
|
|
54
|
+
throw new InvalidResponseError("header names must be strings");
|
|
55
|
+
}
|
|
56
|
+
const value = headers[name];
|
|
57
|
+
if (typeof value !== "string") {
|
|
58
|
+
throw new InvalidResponseError("header values must be strings", {
|
|
59
|
+
headerName: name,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
entries.push([name, value]);
|
|
63
|
+
}
|
|
64
|
+
return entries;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error instanceof InvalidResponseError)
|
|
68
|
+
throw error;
|
|
69
|
+
throw new InvalidResponseError("headers could not be read", {
|
|
70
|
+
cause: errorMessage(error),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function normalizeHeadersWithPlatform(entries, PlatformHeaders) {
|
|
75
|
+
try {
|
|
76
|
+
const normalized = {};
|
|
77
|
+
for (const [name, value] of entries) {
|
|
78
|
+
try {
|
|
79
|
+
const headers = new PlatformHeaders([[name, value]]);
|
|
80
|
+
normalized[name] = headers.get(name) ?? value;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new InvalidResponseError("header is invalid", {
|
|
84
|
+
cause: errorMessage(error),
|
|
85
|
+
headerName: name,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return normalized;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error instanceof InvalidResponseError)
|
|
93
|
+
throw error;
|
|
94
|
+
throw new InvalidResponseError("headers could not be normalized", {
|
|
95
|
+
cause: errorMessage(error),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function normalizeHeadersWithoutPlatform(entries) {
|
|
100
|
+
const normalized = {};
|
|
101
|
+
for (const [name, value] of entries) {
|
|
102
|
+
if (!HEADER_NAME_PATTERN.test(name) || hasInvalidHeaderValue(value)) {
|
|
103
|
+
throw new InvalidResponseError("header is invalid", {
|
|
104
|
+
headerName: name,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
normalized[name] = value.replace(/^[\t ]+|[\t ]+$/g, "");
|
|
108
|
+
}
|
|
109
|
+
return normalized;
|
|
110
|
+
}
|
|
111
|
+
function normalizeHeaders(headers) {
|
|
112
|
+
const entries = headerEntries(headers);
|
|
113
|
+
const seenNames = new Set();
|
|
114
|
+
for (const [name, value] of entries) {
|
|
115
|
+
const normalizedName = name.toLowerCase();
|
|
116
|
+
if (seenNames.has(normalizedName)) {
|
|
117
|
+
throw new InvalidResponseError("header names must be unique", {
|
|
118
|
+
headerName: name,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (!HEADER_NAME_PATTERN.test(name) || hasInvalidHeaderValue(value)) {
|
|
122
|
+
throw new InvalidResponseError("header is invalid", {
|
|
123
|
+
headerName: name,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
seenNames.add(normalizedName);
|
|
127
|
+
}
|
|
128
|
+
const PlatformHeaders = globalThis.Headers;
|
|
129
|
+
return typeof PlatformHeaders === "function"
|
|
130
|
+
? normalizeHeadersWithPlatform(entries, PlatformHeaders)
|
|
131
|
+
: normalizeHeadersWithoutPlatform(entries);
|
|
132
|
+
}
|
|
133
|
+
function copyBinaryBody(body) {
|
|
134
|
+
try {
|
|
135
|
+
if (body instanceof Uint8Array) {
|
|
136
|
+
// Uint8Array.prototype.slice species-creates, so subclasses such as
|
|
137
|
+
// Node's Buffer keep their type while the bytes are still copied.
|
|
138
|
+
// body.slice() would not: Buffer overrides slice() to return a view.
|
|
139
|
+
return Uint8Array.prototype.slice.call(body);
|
|
140
|
+
}
|
|
141
|
+
const source = body instanceof ArrayBuffer
|
|
142
|
+
? new Uint8Array(body)
|
|
143
|
+
: new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
|
|
144
|
+
return Uint8Array.from(source);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw new InvalidResponseError("binary body could not be copied", {
|
|
148
|
+
cause: errorMessage(error),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function bodyType(value) {
|
|
153
|
+
if (value === null)
|
|
154
|
+
return "null";
|
|
155
|
+
if (typeof value !== "object")
|
|
156
|
+
return typeof value;
|
|
157
|
+
try {
|
|
158
|
+
return Object.prototype.toString.call(value);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return "object";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function hasFunctionProperty(value, property) {
|
|
165
|
+
return typeof Reflect.get(value, property) === "function";
|
|
166
|
+
}
|
|
167
|
+
function assertJsonCompatible(value) {
|
|
168
|
+
if (value === null)
|
|
169
|
+
return;
|
|
170
|
+
switch (typeof value) {
|
|
171
|
+
case "boolean":
|
|
172
|
+
case "string":
|
|
173
|
+
return;
|
|
174
|
+
case "number":
|
|
175
|
+
if (Number.isFinite(value))
|
|
176
|
+
return;
|
|
177
|
+
throw new InvalidResponseError("body contains a non-finite number", {
|
|
178
|
+
bodyType: "number",
|
|
179
|
+
});
|
|
180
|
+
case "undefined":
|
|
181
|
+
case "function":
|
|
182
|
+
case "symbol":
|
|
183
|
+
case "bigint":
|
|
184
|
+
throw new InvalidResponseError(`body contains an unsupported ${typeof value} value`, { bodyType: typeof value });
|
|
185
|
+
case "object":
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
if (isBinaryBody(value)) {
|
|
190
|
+
throw new InvalidResponseError("binary values are supported only as the top-level body", { bodyType: bodyType(value) });
|
|
191
|
+
}
|
|
192
|
+
if (hasFunctionProperty(value, "then") ||
|
|
193
|
+
hasFunctionProperty(value, "getReader") ||
|
|
194
|
+
hasFunctionProperty(value, "getWriter") ||
|
|
195
|
+
(hasFunctionProperty(value, "pipe") &&
|
|
196
|
+
hasFunctionProperty(value, "on")) ||
|
|
197
|
+
hasFunctionProperty(value, Symbol.asyncIterator)) {
|
|
198
|
+
throw new InvalidResponseError("promise, iterable, and stream bodies are unsupported", { bodyType: bodyType(value) });
|
|
199
|
+
}
|
|
200
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
201
|
+
if (typeof key === "symbol" &&
|
|
202
|
+
Object.getOwnPropertyDescriptor(value, key)?.enumerable) {
|
|
203
|
+
throw new InvalidResponseError("body contains an enumerable symbol property", { bodyType: bodyType(value) });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!Array.isArray(value) &&
|
|
207
|
+
Object.prototype.toString.call(value) !== "[object Object]") {
|
|
208
|
+
throw new InvalidResponseError("body contains an unsupported object", {
|
|
209
|
+
bodyType: bodyType(value),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
if (error instanceof InvalidResponseError)
|
|
215
|
+
throw error;
|
|
216
|
+
throw new InvalidResponseError("body could not be inspected", {
|
|
217
|
+
bodyType: bodyType(value),
|
|
218
|
+
cause: errorMessage(error),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function stringifyJsonBody(body) {
|
|
223
|
+
try {
|
|
224
|
+
const serialized = JSON.stringify(body, (_key, value) => {
|
|
225
|
+
assertJsonCompatible(value);
|
|
226
|
+
return value;
|
|
227
|
+
});
|
|
228
|
+
if (serialized !== undefined)
|
|
229
|
+
return serialized;
|
|
230
|
+
throw new InvalidResponseError("body did not produce JSON", {
|
|
231
|
+
bodyType: bodyType(body),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (error instanceof InvalidResponseError)
|
|
236
|
+
throw error;
|
|
237
|
+
throw new InvalidResponseError("body is not JSON-serializable", {
|
|
238
|
+
bodyType: bodyType(body),
|
|
239
|
+
cause: errorMessage(error),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function normalizeBody(body) {
|
|
244
|
+
if (body === undefined || typeof body === "string")
|
|
245
|
+
return body;
|
|
246
|
+
if (isBinaryBody(body))
|
|
247
|
+
return copyBinaryBody(body);
|
|
248
|
+
return JSON.parse(stringifyJsonBody(body));
|
|
249
|
+
}
|
|
250
|
+
function removeFramingHeaders(headers, preserveContentLength = false) {
|
|
251
|
+
for (const name of Object.keys(headers)) {
|
|
252
|
+
const normalizedName = name.toLowerCase();
|
|
253
|
+
if (FRAMING_HEADERS.has(normalizedName) &&
|
|
254
|
+
!(preserveContentLength && normalizedName === "content-length")) {
|
|
255
|
+
delete headers[name];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function removeHopByHopHeaders(headers) {
|
|
260
|
+
for (const name of Object.keys(headers)) {
|
|
261
|
+
if (HOP_BY_HOP_HEADERS.has(name.toLowerCase()))
|
|
262
|
+
delete headers[name];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Validate and stabilize a response before it reaches a transport adapter.
|
|
267
|
+
*/
|
|
268
|
+
export function normalizeResponse(response, method) {
|
|
269
|
+
const status = response.status;
|
|
270
|
+
validateStatus(status);
|
|
271
|
+
const headers = normalizeHeaders(response.headers ?? {});
|
|
272
|
+
const normalizedMethod = method.toUpperCase();
|
|
273
|
+
const body = normalizedMethod === "HEAD" || BODY_FORBIDDEN_STATUSES.has(status)
|
|
274
|
+
? undefined
|
|
275
|
+
: normalizeBody(response.body);
|
|
276
|
+
// HEAD and 304 may keep an entity Content-Length (RFC 9110), but 204/205
|
|
277
|
+
// never carry one. Trailer and Transfer-Encoding are always removed —
|
|
278
|
+
// Node's writeHead rejects them on bodyless responses, killing the socket
|
|
279
|
+
// before any bytes reach the client.
|
|
280
|
+
if (status === 204 || status === 205) {
|
|
281
|
+
removeFramingHeaders(headers);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
removeFramingHeaders(headers, normalizedMethod === "HEAD" || status === 304);
|
|
285
|
+
}
|
|
286
|
+
// A hop-by-hop header belongs to the connection, which the transport owns:
|
|
287
|
+
// a route that emits `Connection: close` announces a close the server will
|
|
288
|
+
// not perform, and a conformant client then discards the next response on
|
|
289
|
+
// that socket. Adapters that genuinely mean it (an ingress rejection) add it
|
|
290
|
+
// after normalization, through their own extra-headers channel.
|
|
291
|
+
removeHopByHopHeaders(headers);
|
|
292
|
+
return {
|
|
293
|
+
status,
|
|
294
|
+
body,
|
|
295
|
+
headers,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Encode a response body using its normalized content type semantics.
|
|
300
|
+
*/
|
|
301
|
+
export function serializeResponseBody(response) {
|
|
302
|
+
const status = response.status;
|
|
303
|
+
validateStatus(status);
|
|
304
|
+
if (BODY_FORBIDDEN_STATUSES.has(status))
|
|
305
|
+
return undefined;
|
|
306
|
+
const body = response.body;
|
|
307
|
+
if (body === undefined)
|
|
308
|
+
return undefined;
|
|
309
|
+
if (isBinaryBody(body))
|
|
310
|
+
return copyBinaryBody(body);
|
|
311
|
+
// A string body is treated as pre-serialized wire bytes regardless of
|
|
312
|
+
// content type: quoting it under application/json would double-encode
|
|
313
|
+
// routes that return JSON.stringify(...) themselves.
|
|
314
|
+
const serialized = typeof body === "string" ? body : stringifyJsonBody(body);
|
|
315
|
+
return new TextEncoder().encode(serialized);
|
|
316
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-parser.d.ts","sourceRoot":"","sources":["../src/response-parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response-parser.d.ts","sourceRoot":"","sources":["../src/response-parser.ts"],"names":[],"mappings":"AAwEA;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,OAAO,CAAC,WAAW,GAC/B,OAAO,CAAC,QAAQ,CAuElB"}
|
package/dist/response-parser.js
CHANGED
|
@@ -1,12 +1,47 @@
|
|
|
1
1
|
import { isBinaryBody } from "./binary.js";
|
|
2
2
|
import { isStatusTuple } from "./constants.js";
|
|
3
|
+
import { InvalidResponseError } from "./errors.js";
|
|
3
4
|
const BINARY_CONTENT_TYPE = "application/octet-stream";
|
|
5
|
+
/**
|
|
6
|
+
* Take ownership of caller-supplied response headers.
|
|
7
|
+
*
|
|
8
|
+
* Parsing injects a content type into the header record, so the caller's object
|
|
9
|
+
* must never be aliased — a generator reusing a module-level header object would
|
|
10
|
+
* otherwise leak the content type of one response into the next. Only the shape
|
|
11
|
+
* is checked here; per-value type checks stay in `normalizeResponse` so its
|
|
12
|
+
* distinct messages ("header names/values must be strings") are preserved.
|
|
13
|
+
*/
|
|
14
|
+
function toOwnHeaderRecord(value) {
|
|
15
|
+
if (value === undefined)
|
|
16
|
+
return {};
|
|
17
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
18
|
+
throw new InvalidResponseError("headers must be a string record");
|
|
19
|
+
}
|
|
20
|
+
// Per-value types are `normalizeResponse`'s job (it keeps its own distinct
|
|
21
|
+
// message), so a non-string value is carried through here rather than
|
|
22
|
+
// rejected; this pass only shape-checks and detaches the caller's object.
|
|
23
|
+
const record = {};
|
|
24
|
+
Object.assign(record, value);
|
|
25
|
+
return record;
|
|
26
|
+
}
|
|
4
27
|
function hasContentType(headers) {
|
|
5
28
|
return Object.keys(headers).some((header) => header.toLowerCase() === "content-type");
|
|
6
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Detect the object response envelope `{ status, body, headers? }`.
|
|
32
|
+
*
|
|
33
|
+
* Detection is by shape, so a legitimate domain object carrying a numeric
|
|
34
|
+
* `status` next to a `body` is unwrapped instead of being delivered as the
|
|
35
|
+
* payload. Callers who need to return such a shape as data should nest it or
|
|
36
|
+
* use an explicit `[status, body]` tuple for the envelope. An object whose
|
|
37
|
+
* `headers` is present but not a string record is deliberately NOT an envelope
|
|
38
|
+
* and is delivered whole — plugins that inspect responses must use this same
|
|
39
|
+
* rule (see `@schmock/validation`) or they will judge an undelivered payload.
|
|
40
|
+
*/
|
|
7
41
|
function isResponseObject(value) {
|
|
8
42
|
return (typeof value === "object" &&
|
|
9
43
|
value !== null &&
|
|
44
|
+
!Array.isArray(value) &&
|
|
10
45
|
"status" in value &&
|
|
11
46
|
typeof value.status === "number" &&
|
|
12
47
|
"body" in value &&
|
|
@@ -17,6 +52,7 @@ function isResponseObject(value) {
|
|
|
17
52
|
function isStringRecord(value) {
|
|
18
53
|
return (typeof value === "object" &&
|
|
19
54
|
value !== null &&
|
|
55
|
+
!Array.isArray(value) &&
|
|
20
56
|
Object.values(value).every((entry) => typeof entry === "string"));
|
|
21
57
|
}
|
|
22
58
|
/**
|
|
@@ -32,12 +68,13 @@ export function parseResponse(result, routeConfig) {
|
|
|
32
68
|
if (isResponseObject(result)) {
|
|
33
69
|
status = result.status;
|
|
34
70
|
body = result.body;
|
|
35
|
-
headers = result.headers
|
|
71
|
+
headers = toOwnHeaderRecord(result.headers);
|
|
36
72
|
tupleFormat = true;
|
|
37
73
|
}
|
|
38
74
|
else if (isStatusTuple(result)) {
|
|
39
75
|
// Handle tuple response format [status, body, headers?]
|
|
40
|
-
[status, body
|
|
76
|
+
[status, body] = result;
|
|
77
|
+
headers = toOwnHeaderRecord(result[2]);
|
|
41
78
|
tupleFormat = true;
|
|
42
79
|
}
|
|
43
80
|
// Handle null/undefined responses with 204 No Content
|
package/dist/route-matcher.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ export declare function findRoute(method: Schmock.HttpMethod, path: string, stat
|
|
|
19
19
|
/**
|
|
20
20
|
* Extract parameter values from path based on route pattern
|
|
21
21
|
* Maps capture groups from regex match to parameter names
|
|
22
|
+
*
|
|
23
|
+
* Matching runs on the ENCODED path so `%2F` cannot act as a separator;
|
|
24
|
+
* captures are decoded afterwards, so a generator receives readable values.
|
|
22
25
|
*/
|
|
23
26
|
export declare function extractParams(route: CompiledCallableRoute, path: string): Record<string, string>;
|
|
24
27
|
//# sourceMappingURL=route-matcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-matcher.d.ts","sourceRoot":"","sources":["../src/route-matcher.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,CAAC,SAAS,GACrB,GAAG,IAAI,OAAO,CAAC,iBAAiB,CAElC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAChD,MAAM,EAAE,qBAAqB,EAAE,GAC9B,qBAAqB,GAAG,SAAS,CAmBnC;AAED
|
|
1
|
+
{"version":3,"file":"route-matcher.d.ts","sourceRoot":"","sources":["../src/route-matcher.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,CAAC,SAAS,GACrB,GAAG,IAAI,OAAO,CAAC,iBAAiB,CAElC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAChD,MAAM,EAAE,qBAAqB,EAAE,GAC9B,qBAAqB,GAAG,SAAS,CAmBnC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxB"}
|
package/dist/route-matcher.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { normalizePath } from "./constants.js";
|
|
1
|
+
import { decodePathSegment, normalizePath } from "./constants.js";
|
|
2
2
|
export function isGeneratorFunction(gen) {
|
|
3
3
|
return typeof gen === "function";
|
|
4
4
|
}
|
|
@@ -26,14 +26,20 @@ export function findRoute(method, path, staticRoutes, routes) {
|
|
|
26
26
|
/**
|
|
27
27
|
* Extract parameter values from path based on route pattern
|
|
28
28
|
* Maps capture groups from regex match to parameter names
|
|
29
|
+
*
|
|
30
|
+
* Matching runs on the ENCODED path so `%2F` cannot act as a separator;
|
|
31
|
+
* captures are decoded afterwards, so a generator receives readable values.
|
|
29
32
|
*/
|
|
30
33
|
export function extractParams(route, path) {
|
|
31
34
|
const match = path.match(route.pattern);
|
|
32
35
|
if (!match)
|
|
33
36
|
return {};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return params
|
|
37
|
+
// Object.fromEntries defines own properties, so a parameter named
|
|
38
|
+
// `__proto__` (or any other Object.prototype key) survives instead of being
|
|
39
|
+
// swallowed by the prototype setter. The prototype itself is retained so
|
|
40
|
+
// generators can still call params.hasOwnProperty(...).
|
|
41
|
+
return Object.fromEntries(route.params.map((param, index) => [
|
|
42
|
+
param,
|
|
43
|
+
decodePathSegment(match[index + 1]),
|
|
44
|
+
]));
|
|
39
45
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export type Schema = Schmock.Schema;
|
|
2
|
+
export type SchemaDefinition = Schmock.SchemaDefinition;
|
|
1
3
|
export type HttpMethod = Schmock.HttpMethod;
|
|
2
4
|
export type RouteKey = Schmock.RouteKey;
|
|
3
5
|
export type ResponseBody = Schmock.ResponseBody;
|
|
@@ -17,15 +19,18 @@ export type StaticData = Schmock.StaticData;
|
|
|
17
19
|
export type RequestRecord = Schmock.RequestRecord;
|
|
18
20
|
export type ServerInfo = Schmock.ServerInfo;
|
|
19
21
|
export type RouteInfo = Schmock.RouteInfo;
|
|
22
|
+
export type ResourceOverride = Schmock.ResourceOverride;
|
|
23
|
+
export type ResponseHeaderDef = Schmock.ResponseHeaderDef;
|
|
24
|
+
export type CrudOperationMeta = Schmock.CrudOperationMeta;
|
|
20
25
|
export type SchemaGenerationContext = Schmock.SchemaGenerationContext;
|
|
21
26
|
export type FakerPluginOptions = Schmock.FakerPluginOptions;
|
|
22
27
|
export type ExpressAdapterOptions = Schmock.ExpressAdapterOptions;
|
|
23
28
|
export type AngularAdapterOptions = Schmock.AngularAdapterOptions;
|
|
24
29
|
export type OpenApiOptions = Schmock.OpenApiOptions;
|
|
30
|
+
export type OpenApiCallbackRequest = Schmock.OpenApiCallbackRequest;
|
|
31
|
+
export type OpenApiCallbackOptions = Schmock.OpenApiCallbackOptions;
|
|
25
32
|
export type SeedSource = Schmock.SeedSource;
|
|
26
33
|
export type SeedConfig = Schmock.SeedConfig;
|
|
27
|
-
export type CliOptions = Schmock.CliOptions;
|
|
28
|
-
export type CliServer = Schmock.CliServer;
|
|
29
34
|
export type AdapterRequest = Schmock.AdapterRequest;
|
|
30
35
|
export type AdapterResponse = Schmock.AdapterResponse;
|
|
31
36
|
export type InterceptOptions = Schmock.InterceptOptions;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACxC,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACxC,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;AAC9C,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;AAC1C,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;AAC1D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AACpC,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;AAC1C,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;AAC5D,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;AAClE,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AACpC,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;AACxD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACxC,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AACxC,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;AAC9C,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;AAC1C,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;AAC1D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AACpC,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;AAC1C,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;AACxD,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;AAC1D,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;AAC1D,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;AAC5D,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;AAClE,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;AACpE,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;AACpE,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;AAC5C,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;AACpD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;AACtD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;AACxD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;AACtD,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC"}
|