@schmock/core 2.4.1 → 2.6.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/README.md +129 -0
- package/dist/abort.d.ts +11 -1
- package/dist/abort.js +13 -2
- package/dist/adapter.d.ts +21 -0
- package/dist/adapter.js +19 -0
- package/dist/admission.d.ts +21 -0
- package/dist/admission.js +39 -0
- package/dist/binary.d.ts +0 -1
- package/dist/builder.d.ts +16 -32
- package/dist/builder.js +425 -904
- package/dist/constants.d.ts +33 -2
- package/dist/constants.js +73 -1
- package/dist/debug-logger.d.ts +10 -0
- package/dist/debug-logger.js +31 -0
- package/dist/delay.d.ts +12 -0
- package/dist/delay.js +37 -0
- package/dist/errors.d.ts +13 -2
- package/dist/errors.js +21 -2
- package/dist/events.d.ts +17 -0
- package/dist/events.js +58 -0
- package/dist/generations.d.ts +48 -0
- package/dist/generations.js +82 -0
- package/dist/headers.d.ts +27 -0
- package/dist/headers.js +57 -0
- package/dist/helpers.d.ts +9 -10
- package/dist/helpers.js +4 -1
- package/dist/history.d.ts +56 -0
- package/dist/history.js +151 -0
- package/dist/http-helpers.d.ts +110 -5
- package/dist/http-helpers.js +328 -46
- package/dist/index.d.ts +295 -31
- package/dist/index.js +17 -9
- package/dist/interceptor.d.ts +40 -10
- package/dist/interceptor.js +412 -178
- package/dist/node-server.d.ts +27 -0
- package/dist/node-server.js +166 -0
- package/dist/parser.d.ts +0 -1
- package/dist/parser.js +145 -22
- package/dist/plugin-hooks.d.ts +57 -0
- package/dist/plugin-hooks.js +276 -0
- package/dist/plugin-pipeline.d.ts +0 -1
- package/dist/plugin-pipeline.js +25 -4
- package/dist/response-normalizer.d.ts +36 -1
- package/dist/response-normalizer.js +102 -0
- package/dist/response-parser.d.ts +19 -1
- package/dist/response-parser.js +77 -19
- package/dist/route-matcher.d.ts +0 -1
- package/dist/route-table.d.ts +64 -0
- package/dist/route-table.js +220 -0
- package/dist/snapshot.d.ts +14 -0
- package/dist/snapshot.js +98 -0
- package/dist/types.d.ts +34 -1
- package/package.json +8 -3
- package/dist/abort.d.ts.map +0 -1
- package/dist/binary.d.ts.map +0 -1
- package/dist/builder.d.ts.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/helpers.d.ts.map +0 -1
- package/dist/http-helpers.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interceptor.d.ts.map +0 -1
- package/dist/parser.d.ts.map +0 -1
- package/dist/plugin-pipeline.d.ts.map +0 -1
- package/dist/response-normalizer.d.ts.map +0 -1
- package/dist/response-parser.d.ts.map +0 -1
- package/dist/route-matcher.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,22 @@ namespace Schmock {
|
|
|
112
112
|
*/
|
|
113
113
|
type RouteKey = `${HttpMethod} /${string}`;
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* What a synchronous plugin hook (`install`, `uninstall`) may return: any
|
|
117
|
+
* value except a thenable, which is ignored. A thenable would mean the hook
|
|
118
|
+
* finishes later, which the synchronous install contract cannot honour.
|
|
119
|
+
*/
|
|
120
|
+
type PluginHookResult =
|
|
121
|
+
| void
|
|
122
|
+
| undefined
|
|
123
|
+
| null
|
|
124
|
+
| string
|
|
125
|
+
| number
|
|
126
|
+
| boolean
|
|
127
|
+
| bigint
|
|
128
|
+
| symbol
|
|
129
|
+
| (object & { then?: never });
|
|
130
|
+
|
|
115
131
|
/**
|
|
116
132
|
* Plugin interface for extending Schmock functionality
|
|
117
133
|
*/
|
|
@@ -125,16 +141,24 @@ namespace Schmock {
|
|
|
125
141
|
* Called once when the plugin is added via .pipe()
|
|
126
142
|
* Route registrations are committed atomically only when this hook returns
|
|
127
143
|
* synchronously. The scoped instance must not be retained or used later.
|
|
128
|
-
*
|
|
144
|
+
*
|
|
145
|
+
* Returning a Promise is unsupported: `pipe()` rejects it at runtime with
|
|
146
|
+
* `PLUGIN_ASYNC_INSTALL_UNSUPPORTED`, and the return type makes an
|
|
147
|
+
* `async install()` a compile error too. Any other return value is
|
|
148
|
+
* accepted and ignored, so an expression-bodied arrow that registers a
|
|
149
|
+
* route (`install: (mock) => mock("GET /health", { ok: true })`, which
|
|
150
|
+
* returns the instance) type-checks as it always has.
|
|
129
151
|
* @param instance - A synchronous, installation-scoped callable instance
|
|
130
152
|
*/
|
|
131
|
-
install?(instance: CallableMockInstance):
|
|
153
|
+
install?(instance: CallableMockInstance): PluginHookResult;
|
|
132
154
|
|
|
133
155
|
/**
|
|
134
156
|
* Called during reset after every request admitted with this plugin settles.
|
|
135
|
-
* Cleanup runs in reverse registration order and must complete synchronously
|
|
157
|
+
* Cleanup runs in reverse registration order and must complete synchronously;
|
|
158
|
+
* as with `install`, an async hook is a compile error and any other return
|
|
159
|
+
* value is ignored.
|
|
136
160
|
*/
|
|
137
|
-
uninstall?(instance: CallableMockInstance):
|
|
161
|
+
uninstall?(instance: CallableMockInstance): PluginHookResult;
|
|
138
162
|
|
|
139
163
|
/**
|
|
140
164
|
* Inspect or transform a request before its route generator executes.
|
|
@@ -168,6 +192,22 @@ namespace Schmock {
|
|
|
168
192
|
error: Error,
|
|
169
193
|
context: PluginContext,
|
|
170
194
|
): Error | ResponseResult | void | Promise<Error | ResponseResult | void>;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Observe what a client finally received. Called once for each request this
|
|
198
|
+
* mock settled through fetch interception (`mock.intercept()`, and the
|
|
199
|
+
* service-worker relay built on its leases): answered, failed, or aborted
|
|
200
|
+
* while the mock was answering it. It runs after every adapter hook, so it
|
|
201
|
+
* sees `beforeResponse` and `errorFormatter` output, the 404 for an
|
|
202
|
+
* unrouted request and the 400 for a malformed JSON body when passthrough
|
|
203
|
+
* is off. Not called for requests passed on to the network, for
|
|
204
|
+
* `mock.handle()`, or for requests that arrived before the last `reset()`
|
|
205
|
+
* or before this plugin was piped. Observation only: each observer gets its
|
|
206
|
+
* own frozen snapshot (bodies are copies), the return value is ignored, and
|
|
207
|
+
* a throw or rejection is logged under the `plugin` debug category without
|
|
208
|
+
* reaching the client.
|
|
209
|
+
*/
|
|
210
|
+
onExchange?(exchange: Exchange): void | Promise<void>;
|
|
171
211
|
}
|
|
172
212
|
|
|
173
213
|
/**
|
|
@@ -651,8 +691,15 @@ namespace Schmock {
|
|
|
651
691
|
response: AdapterResponse,
|
|
652
692
|
request: AdapterRequest,
|
|
653
693
|
) => AdapterResponse | void | Promise<AdapterResponse | void>;
|
|
654
|
-
/**
|
|
655
|
-
|
|
694
|
+
/**
|
|
695
|
+
* Format errors into custom response bodies.
|
|
696
|
+
*
|
|
697
|
+
* `request` is passed the way the Express and Angular adapters pass
|
|
698
|
+
* theirs: the request as routed, after `beforeRequest` once that hook has
|
|
699
|
+
* returned. When the request body itself could not be read, it is the
|
|
700
|
+
* incoming request without a body.
|
|
701
|
+
*/
|
|
702
|
+
errorFormatter?: (error: Error, request: AdapterRequest) => unknown;
|
|
656
703
|
}
|
|
657
704
|
|
|
658
705
|
interface InterceptHandle {
|
|
@@ -669,6 +716,100 @@ namespace Schmock {
|
|
|
669
716
|
readonly active: boolean;
|
|
670
717
|
}
|
|
671
718
|
|
|
719
|
+
// ===== Transport Primitives =====
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* A route result taken apart the way core's response parser reads it.
|
|
723
|
+
* Returned by `getResponseParts()`.
|
|
724
|
+
*
|
|
725
|
+
* - `"object"`: a `{ status, body, headers? }` envelope. `headers`, when
|
|
726
|
+
* present, must be a string record, or the value is not an envelope.
|
|
727
|
+
* - `"tuple"`: `[status, body]` or `[status, body, headers]`.
|
|
728
|
+
* - `"plain"`: anything else, delivered whole as the body.
|
|
729
|
+
*/
|
|
730
|
+
interface ResponseParts {
|
|
731
|
+
/** The status core answers with: a plain `null`/`undefined` body is 204. */
|
|
732
|
+
status: number;
|
|
733
|
+
/** The body element as carried. Core sends no body for `null`/`undefined`. */
|
|
734
|
+
body: unknown;
|
|
735
|
+
/**
|
|
736
|
+
* A copy of the carried headers. A tuple whose third element is not a
|
|
737
|
+
* string record yields `{}` here, and core rejects it as INVALID_RESPONSE.
|
|
738
|
+
*/
|
|
739
|
+
headers: Record<string, string>;
|
|
740
|
+
kind: "plain" | "tuple" | "object";
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* A parsed `baseUrl` or namespace. Returned by `parsePathPrefix()` and read
|
|
745
|
+
* by `matchPathPrefix()`.
|
|
746
|
+
*/
|
|
747
|
+
interface PathPrefix {
|
|
748
|
+
/** The origin an origin-form prefix names, or `null` for a path prefix. */
|
|
749
|
+
origin: string | null;
|
|
750
|
+
/**
|
|
751
|
+
* The canonical (percent-encoded) path, without a trailing slash; `""`
|
|
752
|
+
* when the prefix is the root and matches every path.
|
|
753
|
+
*/
|
|
754
|
+
path: string;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** Routes one request: the signature of `CallableMockInstance.handle`. */
|
|
758
|
+
type MockRequestHandler = (
|
|
759
|
+
method: HttpMethod,
|
|
760
|
+
path: string,
|
|
761
|
+
options?: RequestOptions,
|
|
762
|
+
) => Promise<Response>;
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* One request admitted against a snapshot of a mock's routes and plugins.
|
|
766
|
+
* `handle` must be called at most once, and `release` exactly once after
|
|
767
|
+
* the request settles, so a `reset()` waits for it before uninstalling.
|
|
768
|
+
* Acquired through `acquireRequestAdmission()` from `@schmock/core/adapter`.
|
|
769
|
+
*/
|
|
770
|
+
interface RequestAdmission {
|
|
771
|
+
handle: MockRequestHandler;
|
|
772
|
+
release(): void;
|
|
773
|
+
/**
|
|
774
|
+
* Whether `handle(method, path)` would reach a route, answered from the
|
|
775
|
+
* same snapshot and by the same resolver `handle` uses: a `false` must
|
|
776
|
+
* never be wrong, or a request a route answers would be passed through.
|
|
777
|
+
* The fetch interceptor asks it, when present, to skip reading the body
|
|
778
|
+
* of a request that will pass through anyway. Admissions from
|
|
779
|
+
* `schmock()` carry it.
|
|
780
|
+
*/
|
|
781
|
+
hasRoute?(method: HttpMethod, path: string): boolean;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* A relay transport's hold on in-page fetch interception, from
|
|
786
|
+
* `acquireFetchRelay()` in `@schmock/core/adapter`. While any hold is
|
|
787
|
+
* active, a fetch the page makes is forwarded to the network unanswered,
|
|
788
|
+
* with exactly the input and init it was called with, for the relay (a
|
|
789
|
+
* service worker) to bring back through `routeRelayedRequest()`.
|
|
790
|
+
*/
|
|
791
|
+
interface FetchRelay {
|
|
792
|
+
/** Hand fetch back to in-page interception once no hold remains. Idempotent. */
|
|
793
|
+
release(): void;
|
|
794
|
+
/** False once released. */
|
|
795
|
+
readonly active: boolean;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/** Input to `buildFormattedErrorResponse()`. */
|
|
799
|
+
interface FormattedErrorOptions {
|
|
800
|
+
/** The `errorFormatter` hook, called exactly once. */
|
|
801
|
+
formatter: (error: Error) => unknown;
|
|
802
|
+
/** The error being formatted. */
|
|
803
|
+
error: Error;
|
|
804
|
+
/**
|
|
805
|
+
* Headers of the response being replaced (e.g. `retry-after`). Kept when
|
|
806
|
+
* they can be sent, minus any content type: a formatted body is JSON.
|
|
807
|
+
*/
|
|
808
|
+
inheritedHeaders?: Record<string, string>;
|
|
809
|
+
/** Request method; a HEAD response carries no body. */
|
|
810
|
+
method: string;
|
|
811
|
+
}
|
|
812
|
+
|
|
672
813
|
// ===== Lifecycle Events =====
|
|
673
814
|
|
|
674
815
|
/**
|
|
@@ -713,6 +854,58 @@ namespace Schmock {
|
|
|
713
854
|
|
|
714
855
|
type SchmockEvent = keyof SchmockEventMap;
|
|
715
856
|
|
|
857
|
+
// ===== Exchange Observation =====
|
|
858
|
+
|
|
859
|
+
/** The request half of an {@link Exchange}: the request as its client sent it, before any adapter `beforeRequest` hook. */
|
|
860
|
+
interface ExchangeRequest {
|
|
861
|
+
/** The method as the client sent it. */
|
|
862
|
+
readonly method: string;
|
|
863
|
+
/** The absolute request URL without its fragment, as `Response.url` reports it (a relative fetch is resolved against the document base). */
|
|
864
|
+
readonly url: string;
|
|
865
|
+
/** Request headers, names lowercased. */
|
|
866
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
867
|
+
/** The body as the mock read it (JSON value, text, form fields, FormData, ArrayBuffer); absent when the request had none or it was never read. The observer's own copy. */
|
|
868
|
+
readonly body?: unknown;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/** The response half of an {@link AnsweredExchange}: what the client received. */
|
|
872
|
+
interface ExchangeResponse {
|
|
873
|
+
readonly status: number;
|
|
874
|
+
/** Headers of the Response the client received, names lowercased. */
|
|
875
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
876
|
+
/** The body before serialization; absent for none (HEAD, 204). The observer's own copy. */
|
|
877
|
+
readonly body?: unknown;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
interface ExchangeBase {
|
|
881
|
+
readonly request: ExchangeRequest;
|
|
882
|
+
/** `performance.now()` when the transport received the request. */
|
|
883
|
+
readonly startTime: number;
|
|
884
|
+
/** `performance.now()` when the client's outcome was settled. */
|
|
885
|
+
readonly endTime: number;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/** The mock answered: `response` is what the client got after `beforeResponse` and `errorFormatter`, including the 404 for an unrouted request and the 400 for a malformed JSON body when passthrough is off. */
|
|
889
|
+
interface AnsweredExchange extends ExchangeBase {
|
|
890
|
+
readonly outcome: "answered";
|
|
891
|
+
readonly response: ExchangeResponse;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/** The client's request rejected with `error` (a hook or handler threw and no errorFormatter replaced it, or the formatter threw). */
|
|
895
|
+
interface FailedExchange extends ExchangeBase {
|
|
896
|
+
readonly outcome: "failed";
|
|
897
|
+
/** Exactly the value the client's request rejected with. */
|
|
898
|
+
readonly error: unknown;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/** The client aborted the request while this mock was answering it. */
|
|
902
|
+
interface AbortedExchange extends ExchangeBase {
|
|
903
|
+
readonly outcome: "aborted";
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/** One request a transport delivered to a mock, as its client saw it end. Passed to `Plugin.onExchange`. */
|
|
907
|
+
type Exchange = AnsweredExchange | FailedExchange | AbortedExchange;
|
|
908
|
+
|
|
716
909
|
// ===== Introspection Types =====
|
|
717
910
|
|
|
718
911
|
interface RouteInfo {
|
|
@@ -771,7 +964,12 @@ namespace Schmock {
|
|
|
771
964
|
* Context for schema-based data generation
|
|
772
965
|
*/
|
|
773
966
|
interface SchemaGenerationContext {
|
|
774
|
-
|
|
967
|
+
/**
|
|
968
|
+
* The schema to generate from. Typed `Schema` so an inline literal may use
|
|
969
|
+
* the `faker`, `schmockNullable` and `schmockTrueProbability` keywords; a
|
|
970
|
+
* plain `JSONSchema7` is still accepted.
|
|
971
|
+
*/
|
|
972
|
+
schema: Schema;
|
|
775
973
|
count?: number;
|
|
776
974
|
overrides?: Record<string, unknown>;
|
|
777
975
|
params?: Record<string, string>;
|
|
@@ -784,7 +982,12 @@ namespace Schmock {
|
|
|
784
982
|
* Options for the faker plugin
|
|
785
983
|
*/
|
|
786
984
|
interface FakerPluginOptions {
|
|
787
|
-
|
|
985
|
+
/**
|
|
986
|
+
* The schema to generate from. Typed `Schema` so an inline literal may use
|
|
987
|
+
* the `faker`, `schmockNullable` and `schmockTrueProbability` keywords; a
|
|
988
|
+
* plain `JSONSchema7` is still accepted.
|
|
989
|
+
*/
|
|
990
|
+
schema: Schema;
|
|
788
991
|
count?: number;
|
|
789
992
|
overrides?: Record<string, unknown>;
|
|
790
993
|
seed?: number;
|
|
@@ -799,6 +1002,10 @@ namespace Schmock {
|
|
|
799
1002
|
|
|
800
1003
|
/**
|
|
801
1004
|
* Configuration options for Express adapter
|
|
1005
|
+
*
|
|
1006
|
+
* @deprecated Import `ExpressAdapterOptions` from `@schmock/express`, which
|
|
1007
|
+
* types `req`/`res` as Express's `Request`/`Response`. This copy types them
|
|
1008
|
+
* `unknown` and will be removed in the next major version.
|
|
802
1009
|
*/
|
|
803
1010
|
interface ExpressAdapterOptions {
|
|
804
1011
|
errorFormatter?: (error: Error, req: unknown) => unknown;
|
|
@@ -825,6 +1032,10 @@ namespace Schmock {
|
|
|
825
1032
|
|
|
826
1033
|
/**
|
|
827
1034
|
* Configuration options for Angular adapter
|
|
1035
|
+
*
|
|
1036
|
+
* @deprecated Import `AngularAdapterOptions` from `@schmock/angular`, which
|
|
1037
|
+
* types `request` as Angular's `HttpRequest`. This copy types it `unknown`
|
|
1038
|
+
* and will be removed in the next major version.
|
|
828
1039
|
*/
|
|
829
1040
|
interface AngularAdapterOptions {
|
|
830
1041
|
baseUrl?: string;
|
|
@@ -832,6 +1043,26 @@ namespace Schmock {
|
|
|
832
1043
|
errorFormatter?: (error: Error, request: unknown) => unknown;
|
|
833
1044
|
transformRequest?: (request: unknown) => AdapterRequestOverride;
|
|
834
1045
|
transformResponse?: (response: Response, request: unknown) => Response;
|
|
1046
|
+
/**
|
|
1047
|
+
* `transformRequest` under the fetch interceptor's name; it may be async,
|
|
1048
|
+
* and returning nothing leaves the request unchanged. When both are set,
|
|
1049
|
+
* `transformRequest` is used.
|
|
1050
|
+
*/
|
|
1051
|
+
beforeRequest?: (
|
|
1052
|
+
request: unknown,
|
|
1053
|
+
) =>
|
|
1054
|
+
| AdapterRequestOverride
|
|
1055
|
+
| void
|
|
1056
|
+
| Promise<AdapterRequestOverride | undefined>;
|
|
1057
|
+
/**
|
|
1058
|
+
* `transformResponse` under the fetch interceptor's name; it may be async,
|
|
1059
|
+
* and returning nothing keeps the response. When both are set,
|
|
1060
|
+
* `transformResponse` is used.
|
|
1061
|
+
*/
|
|
1062
|
+
beforeResponse?: (
|
|
1063
|
+
response: Response,
|
|
1064
|
+
request: unknown,
|
|
1065
|
+
) => Response | void | Promise<Response | undefined>;
|
|
835
1066
|
}
|
|
836
1067
|
|
|
837
1068
|
// ===== OpenAPI Plugin Options =====
|
|
@@ -863,17 +1094,19 @@ namespace Schmock {
|
|
|
863
1094
|
allowHttp?: boolean;
|
|
864
1095
|
/**
|
|
865
1096
|
* Hostnames an `http(s)` `$ref` may target. Empty or omitted means any
|
|
866
|
-
* host, still minus loopback, link-local and
|
|
1097
|
+
* host, still minus loopback, link-local, private and reserved ranges,
|
|
1098
|
+
* checked against every address a host resolves to, so an allow-listed
|
|
1099
|
+
* name that resolves to one is refused too.
|
|
867
1100
|
*/
|
|
868
1101
|
allowedHosts?: string[];
|
|
869
1102
|
/** Per-request timeout for http `$ref`s, in ms. Default 5000. */
|
|
870
1103
|
timeoutMs?: number;
|
|
871
1104
|
/**
|
|
872
|
-
*
|
|
1105
|
+
* Maximum redirect hops to follow for an http `$ref`. Default 0.
|
|
873
1106
|
*
|
|
874
|
-
*
|
|
875
|
-
* `0` refuses
|
|
876
|
-
*
|
|
1107
|
+
* Every hop is checked against `allowHttp` and `allowedHosts` before it
|
|
1108
|
+
* is followed. `0` refuses the first redirect; `n` follows up to `n` hops
|
|
1109
|
+
* and refuses the next one.
|
|
877
1110
|
*/
|
|
878
1111
|
redirects?: number;
|
|
879
1112
|
/** Maximum size of a single http `$ref` document, in bytes. Default 1 MB. */
|
|
@@ -915,18 +1148,27 @@ namespace Schmock {
|
|
|
915
1148
|
/** Replace response schemas for specific routes. Key format: "METHOD /path" or "METHOD /path STATUS" */
|
|
916
1149
|
schemas?: Record<string, import("json-schema").JSONSchema7>;
|
|
917
1150
|
/** Called before generating a response body. Return a schema to replace the original, or void to keep it. */
|
|
918
|
-
onSchema?:
|
|
919
|
-
schema: import("json-schema").JSONSchema7,
|
|
920
|
-
context: {
|
|
921
|
-
method: string;
|
|
922
|
-
path: string;
|
|
923
|
-
params: Record<string, string>;
|
|
924
|
-
query: Record<string, string>;
|
|
925
|
-
headers: Record<string, string>;
|
|
926
|
-
},
|
|
927
|
-
) => import("json-schema").JSONSchema7 | undefined;
|
|
1151
|
+
onSchema?: OnSchemaCallback;
|
|
928
1152
|
}
|
|
929
1153
|
|
|
1154
|
+
/** The request an {@link OnSchemaCallback} is generating a response for. */
|
|
1155
|
+
interface OnSchemaContext {
|
|
1156
|
+
method: string;
|
|
1157
|
+
path: string;
|
|
1158
|
+
params: Record<string, string>;
|
|
1159
|
+
query: Record<string, string>;
|
|
1160
|
+
headers: Record<string, string>;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
* `OpenApiOptions.onSchema`: called before a response body is generated.
|
|
1165
|
+
* Return a schema to replace the original, or `undefined` to keep it.
|
|
1166
|
+
*/
|
|
1167
|
+
type OnSchemaCallback = (
|
|
1168
|
+
schema: import("json-schema").JSONSchema7,
|
|
1169
|
+
context: OnSchemaContext,
|
|
1170
|
+
) => import("json-schema").JSONSchema7 | undefined;
|
|
1171
|
+
|
|
930
1172
|
/**
|
|
931
1173
|
* Seed data source: inline array, file path, or auto-generate count
|
|
932
1174
|
*/
|
|
@@ -963,6 +1205,10 @@ namespace Schmock {
|
|
|
963
1205
|
* How many requests the mock retains for `GET /schmock-admin/history`
|
|
964
1206
|
* (`--admin-history-limit`, default 500). Ignored — history is disabled
|
|
965
1207
|
* entirely — when `admin` is off.
|
|
1208
|
+
*
|
|
1209
|
+
* It becomes the mock's {@link GlobalConfig.maxHistorySize} and applies
|
|
1210
|
+
* only while the admin API is on; it defaults to 500 where a core mock's
|
|
1211
|
+
* history is unbounded.
|
|
966
1212
|
*/
|
|
967
1213
|
adminHistoryLimit?: number;
|
|
968
1214
|
/** Validate the spec against the OpenAPI schema at startup (`--strict`). */
|
|
@@ -1020,6 +1266,7 @@ namespace Schmock {
|
|
|
1020
1266
|
}
|
|
1021
1267
|
}
|
|
1022
1268
|
// >>> schmock ambient namespace <<<
|
|
1269
|
+
import { createFetchInterceptor as createAdapterFetchInterceptor } from "./interceptor.js";
|
|
1023
1270
|
/**
|
|
1024
1271
|
* Create a new Schmock mock instance with callable API.
|
|
1025
1272
|
*
|
|
@@ -1044,13 +1291,30 @@ namespace Schmock {
|
|
|
1044
1291
|
* @returns A callable mock instance
|
|
1045
1292
|
*/
|
|
1046
1293
|
export declare function schmock(config?: Schmock.GlobalConfig): Schmock.CallableMockInstance;
|
|
1294
|
+
/**
|
|
1295
|
+
* @deprecated Use `mock.intercept()`, which also tracks the lease and admits
|
|
1296
|
+
* each request against the mock's routes. Adapter authors who need the raw
|
|
1297
|
+
* interceptor import `createFetchInterceptor` from `@schmock/core/adapter`.
|
|
1298
|
+
* This root export will be removed in the next major version.
|
|
1299
|
+
*/
|
|
1300
|
+
export declare const createFetchInterceptor: typeof createAdapterFetchInterceptor;
|
|
1047
1301
|
export { isBinaryBody } from "./binary.js";
|
|
1048
|
-
export { getResponseException, HTTP_METHODS, isHttpMethod, isRouteNotFound, isStatusTuple, ROUTE_NOT_FOUND_CODE, toHttpMethod, toRouteKey, } from "./constants.js";
|
|
1049
|
-
export { InvalidResponseError, PluginError, ResourceLimitError, RouteDefinitionError, RouteNotFoundError, RouteParseError, SchemaGenerationError, SchemaValidationError, SchmockError, } from "./errors.js";
|
|
1302
|
+
export { getResponseException, HTTP_METHODS, isHttpMethod, isRouteNotFound, isStatusTuple, matchPathPrefix, parsePathPrefix, ROUTE_NOT_FOUND_CODE, toHttpMethod, toRouteKey, } from "./constants.js";
|
|
1303
|
+
export { InvalidHttpMethodError, InvalidResponseError, PluginError, ResourceLimitError, RouteDefinitionError, RouteNotFoundError, RouteParseError, SchemaGenerationError, SchemaValidationError, SchmockError, } from "./errors.js";
|
|
1304
|
+
export { getHeader, redactHeaders, SENSITIVE_HEADER_NAMES, } from "./headers.js";
|
|
1050
1305
|
export { badRequest, created, forbidden, noContent, notFound, paginate, serverError, unauthorized, } from "./helpers.js";
|
|
1051
|
-
export type { HttpIngressErrorCode } from "./http-helpers.js";
|
|
1052
|
-
export { collectBody, HttpIngressError, parseNodeHeaders, parseNodeQuery, writeRejectedSchmockResponse, writeSchmockResponse, } from "./http-helpers.js";
|
|
1053
|
-
export {
|
|
1054
|
-
export {
|
|
1055
|
-
export type { AdapterRequest, AdapterRequestOverride, AdapterResponse,
|
|
1056
|
-
|
|
1306
|
+
export type { HttpErrorReply, HttpIngressErrorCode, NodeRequestLike, NodeResponseLike, ServeNodeRequestOptions, ServeNodeResponseContext, } from "./http-helpers.js";
|
|
1307
|
+
export { collectBody, HttpIngressError, parseNodeHeaders, parseNodeQuery, serveNodeRequest, writeRejectedSchmockResponse, writeSchmockResponse, } from "./http-helpers.js";
|
|
1308
|
+
export { buildFormattedErrorResponse, normalizeResponse, serializeResponseBody, withDefaultContentType, } from "./response-normalizer.js";
|
|
1309
|
+
export { getResponseParts, replaceResponseBody, } from "./response-parser.js";
|
|
1310
|
+
export type { AbortedExchange, AdapterRequest, AdapterRequestOverride, AdapterResponse,
|
|
1311
|
+
/**
|
|
1312
|
+
* @deprecated Import `AngularAdapterOptions` from `@schmock/angular`; this
|
|
1313
|
+
* copy will be removed in the next major version.
|
|
1314
|
+
*/
|
|
1315
|
+
AngularAdapterOptions, AnsweredExchange, CallableMockInstance, CrudOperationMeta, Exchange, ExchangeRequest, ExchangeResponse,
|
|
1316
|
+
/**
|
|
1317
|
+
* @deprecated Import `ExpressAdapterOptions` from `@schmock/express`; this
|
|
1318
|
+
* copy will be removed in the next major version.
|
|
1319
|
+
*/
|
|
1320
|
+
ExpressAdapterOptions, FailedExchange, FakerPluginOptions, FormattedErrorOptions, Generator, GeneratorFunction, GlobalConfig, HttpMethod, InterceptHandle, InterceptOptions, OnSchemaCallback, OnSchemaContext, OpenApiCallbackOptions, OpenApiCallbackRequest, OpenApiOptions, OpenApiRefPolicy, PaginatedResponse, PaginateOptions, PathPrefix, Plugin, PluginContext, PluginHookResult, PluginResult, RequestContext, RequestEndEvent, RequestMatchEvent, RequestNotFoundEvent, RequestOptions, RequestRecord, RequestStartEvent, ResourceOverride, Response, ResponseBody, ResponseHeaderDef, ResponseParts, ResponseResult, RouteConfig, RouteInfo, RouteKey, Schema, SchemaDefinition, SchemaGenerationContext, SchmockEvent, SchmockEventMap, SeedConfig, SeedSource, ServerInfo, StaticData, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { REQUEST_ADMISSION_KEY } from "./admission.js";
|
|
1
2
|
import { CallableMockInstance } from "./builder.js";
|
|
2
|
-
|
|
3
|
+
import { createFetchInterceptor as createAdapterFetchInterceptor } from "./interceptor.js";
|
|
3
4
|
/**
|
|
4
5
|
* Create a new Schmock mock instance with callable API.
|
|
5
6
|
*
|
|
@@ -57,22 +58,29 @@ export function schmock(config) {
|
|
|
57
58
|
close: instance.close.bind(instance),
|
|
58
59
|
intercept: (options) => instance.intercept(options),
|
|
59
60
|
});
|
|
60
|
-
Object.defineProperty(callableInstance,
|
|
61
|
+
Object.defineProperty(callableInstance, REQUEST_ADMISSION_KEY, {
|
|
61
62
|
value: () => instance.createRequestAdmission(),
|
|
62
63
|
});
|
|
63
64
|
instance.setCallableRef(callableInstance);
|
|
64
65
|
return callableInstance;
|
|
65
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* @deprecated Use `mock.intercept()`, which also tracks the lease and admits
|
|
69
|
+
* each request against the mock's routes. Adapter authors who need the raw
|
|
70
|
+
* interceptor import `createFetchInterceptor` from `@schmock/core/adapter`.
|
|
71
|
+
* This root export will be removed in the next major version.
|
|
72
|
+
*/
|
|
73
|
+
export const createFetchInterceptor = createAdapterFetchInterceptor;
|
|
66
74
|
export { isBinaryBody } from "./binary.js";
|
|
67
75
|
// Re-export constants and utilities
|
|
68
|
-
export { getResponseException, HTTP_METHODS, isHttpMethod, isRouteNotFound, isStatusTuple, ROUTE_NOT_FOUND_CODE, toHttpMethod, toRouteKey, } from "./constants.js";
|
|
76
|
+
export { getResponseException, HTTP_METHODS, isHttpMethod, isRouteNotFound, isStatusTuple, matchPathPrefix, parsePathPrefix, ROUTE_NOT_FOUND_CODE, toHttpMethod, toRouteKey, } from "./constants.js";
|
|
69
77
|
// Re-export errors
|
|
70
|
-
export { InvalidResponseError, PluginError, ResourceLimitError, RouteDefinitionError, RouteNotFoundError, RouteParseError, SchemaGenerationError, SchemaValidationError, SchmockError, } from "./errors.js";
|
|
78
|
+
export { InvalidHttpMethodError, InvalidResponseError, PluginError, ResourceLimitError, RouteDefinitionError, RouteNotFoundError, RouteParseError, SchemaGenerationError, SchemaValidationError, SchmockError, } from "./errors.js";
|
|
79
|
+
// Re-export header helpers
|
|
80
|
+
export { getHeader, redactHeaders, SENSITIVE_HEADER_NAMES, } from "./headers.js";
|
|
71
81
|
// Re-export response helpers
|
|
72
82
|
export { badRequest, created, forbidden, noContent, notFound, paginate, serverError, unauthorized, } from "./helpers.js";
|
|
73
83
|
// Re-export HTTP server helpers
|
|
74
|
-
export { collectBody, HttpIngressError, parseNodeHeaders, parseNodeQuery, writeRejectedSchmockResponse, writeSchmockResponse, } from "./http-helpers.js";
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
export { createFetchInterceptor } from "./interceptor.js";
|
|
78
|
-
export { normalizeResponse, serializeResponseBody, } from "./response-normalizer.js";
|
|
84
|
+
export { collectBody, HttpIngressError, parseNodeHeaders, parseNodeQuery, serveNodeRequest, writeRejectedSchmockResponse, writeSchmockResponse, } from "./http-helpers.js";
|
|
85
|
+
export { buildFormattedErrorResponse, normalizeResponse, serializeResponseBody, withDefaultContentType, } from "./response-normalizer.js";
|
|
86
|
+
export { getResponseParts, replaceResponseBody, } from "./response-parser.js";
|
package/dist/interceptor.d.ts
CHANGED
|
@@ -1,15 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Marks an admission whose `handle()` already returns responses normalized
|
|
3
|
+
* for the request method (hop-by-hop headers dropped, a HEAD body stripped):
|
|
4
|
+
* only the admissions a `schmock()` instance of this copy creates. The
|
|
5
|
+
* interceptor re-normalizes the responses of any other admission, such as a
|
|
6
|
+
* hand-written one passed to `createFetchInterceptor`. Deliberately
|
|
7
|
+
* unregistered: an admission from a second copy of `@schmock/core` is simply
|
|
8
|
+
* normalized again.
|
|
9
|
+
*/
|
|
10
|
+
export declare const NORMALIZED_ADMISSION_KEY: unique symbol;
|
|
11
|
+
export type ExchangeObserver = (exchange: Schmock.Exchange) => void;
|
|
12
|
+
/** Called synchronously right before one consultation of a lease; undefined when nothing observes the lease's mock. */
|
|
13
|
+
type ExchangeObservationOpener = () => ExchangeObserver | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Makes every intercepted fetch skip routing and go straight to the baseline
|
|
16
|
+
* until released. Holds stack: fetches resume once every hold is released.
|
|
17
|
+
* It never touches `globalThis.fetch`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function acquireFetchRelay(): Schmock.FetchRelay;
|
|
20
|
+
/**
|
|
21
|
+
* Routes a request that a service worker relayed to the page through the
|
|
22
|
+
* newest session's leases. Resolves `undefined` when nothing answers it (no
|
|
23
|
+
* lease, or a route miss with passthrough) and never calls the baseline fetch,
|
|
24
|
+
* so the caller decides how the request reaches the network. Rejects with the
|
|
25
|
+
* request's abort reason when it is aborted mid-route.
|
|
26
|
+
*/
|
|
27
|
+
export declare function routeRelayedRequest(request: Request): Promise<Response | undefined>;
|
|
6
28
|
/**
|
|
7
29
|
* Create a fetch interceptor that routes requests through mock.handle().
|
|
8
30
|
*
|
|
9
|
-
* `owner` identifies the mock behind the lease. Leases sharing an owner
|
|
10
|
-
*
|
|
11
|
-
*
|
|
31
|
+
* `owner` identifies the mock behind the lease. Leases sharing an owner ask it
|
|
32
|
+
* each distinct effective request (method and path after the lease's own
|
|
33
|
+
* beforeRequest) at most once, so a mock held by several leases runs its
|
|
34
|
+
* handler — and emits its lifecycle events — once per request it is asked.
|
|
12
35
|
*/
|
|
13
|
-
export declare function createFetchInterceptor(handle:
|
|
36
|
+
export declare function createFetchInterceptor(handle: Schmock.MockRequestHandler, options?: Schmock.InterceptOptions, admitRequest?: () => Schmock.RequestAdmission, owner?: symbol): Schmock.InterceptHandle;
|
|
37
|
+
interface FetchLeaseSpec {
|
|
38
|
+
handle: Schmock.MockRequestHandler;
|
|
39
|
+
options?: Schmock.InterceptOptions;
|
|
40
|
+
admitRequest?: () => Schmock.RequestAdmission;
|
|
41
|
+
owner?: symbol;
|
|
42
|
+
observe?: ExchangeObservationOpener;
|
|
43
|
+
}
|
|
44
|
+
export declare function createFetchLease(spec: FetchLeaseSpec): Schmock.InterceptHandle;
|
|
14
45
|
export {};
|
|
15
|
-
//# sourceMappingURL=interceptor.d.ts.map
|