@unshared/client 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,204 @@
1
+ import { MaybeArray, MaybeLiteral, Override } from '@unshared/types';
2
+ import { H as HttpHeader } from './8BFCFxqa.js';
3
+
4
+ declare enum HttpMethod {
5
+ /**
6
+ * The **`CONNECT`** HTTP method requests that a [proxy](https://developer.mozilla.org/en-US/docs/Glossary/Proxy_server) establish a HTTP tunnel to a destination server, and if successful, blindly forward data in both directions until the tunnel is closed.
7
+ *
8
+ * The request target is unique to this method in that it consists of only the host and port number of the tunnel destination, separated by a colon (see [Syntax](#syntax) for details).
9
+ * Any [2XX successful response status code](/en-US/docs/Web/HTTP/Status#successful_responses) means that the proxy will switch to 'tunnel mode' and any data in the success response body is from the server identified by the request target.
10
+ *
11
+ * If a website is behind a proxy and it's enforced via network rules that all external traffic must pass through the proxy, the `CONNECT` method allows you to establish a [TLS](https://developer.mozilla.org/en-US/docs/Glossary/TLS) ([HTTPS](https://developer.mozilla.org/en-US/docs/Glossary/HTTPS)) connection with that website:
12
+ *
13
+ * - The client asks the proxy to tunnel the [TCP](https://developer.mozilla.org/en-US/docs/Glossary/TCP) connection to the desired destination.
14
+ * - The proxy server makes a secure connection to the server on behalf of the client.
15
+ * - Once the connection is established, the proxy server continues to relay the TCP stream to and from the client.
16
+ *
17
+ * Aside from enabling secure access to websites behind proxies, a HTTP tunnel provides a way to allow traffic that would otherwise be restricted (SSH or FTP) over the HTTP(S) protocol.
18
+ *
19
+ * `CONNECT` is a hop-by-hop method, meaning proxies will only forward the `CONNECT` request if there is another inbound proxy in front of the origin server since most origin servers do not implement `CONNECT`.
20
+ *
21
+ * > [!WARNING]
22
+ * > If you are running a proxy that supports `CONNECT`, restrict its use to a set of known ports or a configurable list of safe request targets.
23
+ * > There are significant risks in establishing a tunnel to arbitrary servers, particularly when the destination is a well-known or reserved TCP port that is not intended for Web traffic.
24
+ * > A loosely-configured proxy may be abused to forward traffic such as SMTP to relay spam email, for example.
25
+ */
26
+ CONNECT = "CONNECT",
27
+ /**
28
+ * The **`DELETE`** HTTP method asks the server to delete a specified resource.
29
+ *
30
+ * The `DELETE` method has no defined semantics for the message body, so this should be empty.
31
+ */
32
+ DELETE = "DELETE",
33
+ /**
34
+ * The **`GET`** HTTP method requests a representation of the specified resource.
35
+ * Requests using `GET` should only be used to request data and shouldn't contain a body.
36
+ *
37
+ * > [!NOTE]
38
+ * > The semantics of sending a message body in `GET` requests are undefined.
39
+ * > Some servers may reject the request with a [4XX client error](/en-US/docs/Web/HTTP/Status#client_error_responses) response.
40
+ */
41
+ GET = "GET",
42
+ /**
43
+ * The **`HEAD`** HTTP method requests the metadata of a resource in the form of [headers](/en-US/docs/Web/HTTP/Headers) that the server would have sent if the [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/GET) method was used instead.
44
+ * This method can be used in cases where a URL might produce a large download, for example, a `HEAD` request can read the [Content-Length](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length) header to check the file size before downloading the file with a `GET`.
45
+ *
46
+ * If the response to a `HEAD` request shows that a cached URL response is now outdated, the cached copy is invalidated even if no `GET` request was made.
47
+ *
48
+ * > [!WARNING]
49
+ * > If a response to a `HEAD` request has a body, the response body must be ignored.
50
+ * > Any [representation headers](https://developer.mozilla.org/en-US/docs/glossary/Representation_header) that describe the erroneous body are assumed to describe the response body that a `GET` request would have received.
51
+ */
52
+ HEAD = "HEAD",
53
+ /**
54
+ * The **`OPTIONS`** HTTP method requests permitted communication options for a given URL or server.
55
+ * This can be used to test the allowed HTTP methods for a request, or to determine whether a request would succeed when making a CORS preflighted request.
56
+ * A client can specify a URL with this method, or an asterisk (`*`) to refer to the entire server.
57
+ */
58
+ OPTIONS = "OPTIONS",
59
+ /**
60
+ * The **`PATCH`** HTTP method applies partial modifications to a resource.
61
+ *
62
+ * `PATCH` is somewhat analogous to the "update" concept found in [CRUD](https://developer.mozilla.org/en-US/docs/Glossary/CRUD) (in general, HTTP is different than [CRUD](https://developer.mozilla.org/en-US/docs/Glossary/CRUD), and the two should not be confused).
63
+ *
64
+ * In comparison with [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/PUT), a `PATCH` serves as a set of instructions for modifying a resource, whereas `PUT` represents a complete replacement of the resource.
65
+ * A `PUT` request is always [idempotent](https://developer.mozilla.org/en-US/docs/Glossary/idempotent) (repeating the same request multiple times results in the resource remaining in the same state), whereas a `PATCH` request may not always be idempotent.
66
+ * For instance, if a resource includes an auto-incrementing counter, a `PUT` request will overwrite the counter (since it replaces the entire resource), but a `PATCH` request may not.
67
+ *
68
+ * Like [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/POST), a `PATCH` request can potentially have side effects on other resources.
69
+ *
70
+ * A server can advertise support for `PATCH` by adding it to the list in the [Allow](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Allow) or [Access-Control-Allow-Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods) (for [CORS](/en-US/docs/Web/HTTP/CORS)) response headers.
71
+ * Another implicit indication that `PATCH` is supported is the [Accept-Patch](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Patch) header (usually after an [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/OPTIONS) request on a resource), which lists the media-types the server is able to understand in a `PATCH` request for a resource.
72
+ */
73
+ PATCH = "PATCH",
74
+ /**
75
+ * The **`POST`** HTTP method sends data to the server. The type of the body of the request is indicated by the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) header.
76
+ *
77
+ * The difference between [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/PUT) and `POST` is that `PUT` is [idempotent](https://developer.mozilla.org/en-US/docs/Glossary/idempotent): calling it once is no different from calling it several times successively (there are no _side_ effects).
78
+ * Successive identical `POST` requests may have additional effects, such as creating the same order several times.
79
+ *
80
+ * [HTML forms](/en-US/docs/Learn/Forms) typically send data using `POST` and this usually results in a change on the server.
81
+ * For HTML forms the format/encoding of the body content is determined by the [`enctype`](/en-US/docs/Web/HTML/Element/form#enctype) attribute of the [form](https://developer.mozilla.org/en-US/docs/HTMLElement/form) element or the [`formenctype`](/en-US/docs/Web/HTML/Element/input#formenctype) attribute of the [input") }} or _or_{{HTMLElement("button) elements.
82
+ * The encoding may be one of the following:
83
+ *
84
+ * - `application/x-www-form-urlencoded`: the keys and values are encoded in key-value tuples separated by an ampersand (`&`), with an equals symbol (`=`) between the key and the value (e.g., `first-name=Frida&last-name=Kahlo`).
85
+ * Non-alphanumeric characters in both keys and values are [percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding): this is the reason why this type is not suitable to use with binary data and you should use `multipart/form-data` for this purpose instead.
86
+ * - `multipart/form-data`: each value is sent as a block of data ("body part"), with a user agent-defined delimiter (for example, `boundary="delimiter12345"`) separating each part.
87
+ * The keys are described in the [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header of each part or block of data.
88
+ * - `text/plain`
89
+ *
90
+ * When the `POST` request is sent following a [fetch()](https://developer.mozilla.org/en-US/docs/domxref/Window/fetch) call, or for any other reason than an HTML form, the body can be any type.
91
+ * As described in the HTTP 1.1 specification, `POST` is designed to allow a uniform method to cover the following functions:
92
+ *
93
+ * - Annotation of existing resources
94
+ * - Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles
95
+ * - Adding a new user through a signup form
96
+ * - Providing a block of data, such as the result of submitting a form, to a data-handling process
97
+ * - Extending a database through an append operation
98
+ */
99
+ POST = "POST",
100
+ /**
101
+ * The **`PUT`** HTTP method creates a new resource or replaces a representation of the target resource with the request [content](https://developer.mozilla.org/en-US/docs/Glossary/HTTP_Content).
102
+ *
103
+ * The difference between `PUT` and [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Method/POST) is that `PUT` is [idempotent](https://developer.mozilla.org/en-US/docs/Glossary/idempotent): calling it once is no different from calling it several times successively (there are no _side_ effects).
104
+ */
105
+ PUT = "PUT",
106
+ /**
107
+ * The **`TRACE`** HTTP method performs a message loop-back test along the path to the target resource.
108
+ *
109
+ * The final recipient of the request should reflect the message as received (excluding any fields that might include sensitive data) back to the client as the message body of a [200 OK](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200) response with a [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of `message/http`.
110
+ * The final recipient is either the origin server or the first server to receive a [Max-Forwards](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Max-Forwards) value of `0` in the request.
111
+ *
112
+ * The client must not send [content](https://developer.mozilla.org/en-US/docs/Glossary/HTTP_Content) in the request, or generate headers that might include sensitive data such as user credentials or cookies.
113
+ * Not all servers implement the `TRACE` method, and some server owners have historically disallowed the use of the `TRACE` method due to security concerns.
114
+ * In such cases, a [405 Method Not Allowed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405) [client error response](/en-US/docs/Web/HTTP/Status#client_error_responses) will be sent.
115
+ */
116
+ TRACE = "TRACE"
117
+ }
118
+
119
+ /** An object that can be converted to a query string. */
120
+ type SearchParamsObject = Record<string, MaybeArray<boolean | number | string> | undefined>;
121
+ /** The search array format options. */
122
+ type SearchArrayFormat = 'brackets' | 'comma' | 'flat' | 'indices' | 'path';
123
+ /** Options for the query string conversion. */
124
+ interface ToSearchParamsOptions {
125
+ /**
126
+ * Defines how to handle arrays in the object. There is no standard way to
127
+ * represent arrays in query strings, so this option allows you to choose
128
+ * how to handle them. Additionally, you can provide a custom function to
129
+ * handle it yourself.
130
+ *
131
+ * - `brackets` (default): Convert arrays to `key[]=value&key[]=value` format.
132
+ * - `indices`: Convert arrays to `key[0]=value&key[1]=value` format.
133
+ * - `comma`: Convert arrays to `key=value1,value2` format.
134
+ * - `path`: Convert arrays to `key.0=value&key.1=value` format.
135
+ * - `flat`: Convert arrays to `key=value1&key=value2` format.
136
+ *
137
+ * @default 'flat'
138
+ */
139
+ searchArrayFormat?: SearchArrayFormat;
140
+ }
141
+ /**
142
+ * Convert object to query string parameters. Converting all values to strings
143
+ * and arrays to `key[0]=value&key[1]=value` format.
144
+ *
145
+ * @param object The object to convert to a query string.
146
+ * @param options The query string options.
147
+ * @returns The `URLSearchParams` object.
148
+ */
149
+ declare function toSearchParams(object: SearchParamsObject, options?: ToSearchParamsOptions): URLSearchParams;
150
+
151
+ /** Headers to include in the request. */
152
+ type RequestHeaders = Partial<Record<MaybeLiteral<HttpHeader>, string>>;
153
+ type RequestOptions = Override<RequestInit, {
154
+ /**
155
+ * The method to use for the request.
156
+ *
157
+ * @example 'GET'
158
+ */
159
+ method?: Lowercase<keyof typeof HttpMethod> | Uppercase<keyof typeof HttpMethod>;
160
+ /**
161
+ * The base URL to use for the request. This URL will be used to resolve the
162
+ * path and query parameters of the request.
163
+ *
164
+ * @example 'https://api.example.com'
165
+ */
166
+ baseUrl?: string;
167
+ /**
168
+ * The data to pass to the request. This data will be used to fill the path
169
+ * parameters, query parameters, body, and form data of the request based on
170
+ * the route method.
171
+ */
172
+ data?: Blob | File | FileList | FormData | ReadableStream | Record<string, unknown> | string;
173
+ /**
174
+ * The headers to include in the request.
175
+ */
176
+ headers?: RequestHeaders;
177
+ /**
178
+ * Query parameters to include in the request.
179
+ */
180
+ query?: SearchParamsObject;
181
+ /**
182
+ * The format to use when serializing the query parameters.
183
+ */
184
+ searchArrayFormat?: SearchArrayFormat;
185
+ /**
186
+ * The path parameters to include in the request.
187
+ */
188
+ parameters?: Record<string, number | string>;
189
+ }>;
190
+ interface RequestContext {
191
+ url?: URL;
192
+ init: RequestInit;
193
+ }
194
+ /**
195
+ * Resolves the request body and/or query parameters based on the method type. This function
196
+ * will mutate the `init` object to include the request body and headers based on the data type.
197
+ *
198
+ * @param route The name of the route to fetch.
199
+ * @param options The options to pass to the request.
200
+ * @returns The URL and the `RequestInit` object.
201
+ */
202
+ declare function parseRequest(route: string, options?: RequestOptions): RequestContext;
203
+
204
+ export { HttpMethod as H, type RequestHeaders as R, type SearchParamsObject as S, type ToSearchParamsOptions as T, type RequestOptions as a, type RequestContext as b, type SearchArrayFormat as c, parseRequest as p, toSearchParams as t };
@@ -0,0 +1,188 @@
1
+ import { MaybeArray, Pretty, UnionMerge, Override, CollectKey, StringSplit, LooseDeep } from '@unshared/types';
2
+ import { H as HttpHeader } from './8BFCFxqa.js';
3
+
4
+ declare namespace OpenAPIV2 {
5
+ type ServerUrl<T> = T extends {
6
+ host: infer Host extends string;
7
+ basePath?: infer BasePath extends string;
8
+ schemes?: Array<infer Scheme extends string>;
9
+ } ? `${Scheme}://${Host}${BasePath}` : string;
10
+ /*************************************************************************/
11
+ /*************************************************************************/
12
+ type InferSchemaObject<T> = T extends {
13
+ properties: infer P extends Record<string, any>;
14
+ required: Array<infer R extends string>;
15
+ } ? ({
16
+ [K in keyof P as K extends R ? K : never]: InferSchema<P[K]>;
17
+ } & {
18
+ [K in keyof P as K extends R ? never : K]?: InferSchema<P[K]>;
19
+ }) : T extends {
20
+ properties: infer P extends Record<string, any>;
21
+ } ? {
22
+ [K in keyof P]?: InferSchema<P[K]>;
23
+ } : Record<string, unknown>;
24
+ type InferSchemaArray<T> = T extends {
25
+ items: MaybeArray<infer U>;
26
+ additionalItems: MaybeArray<infer V>;
27
+ } ? Array<InferSchema<U | V>> : T extends {
28
+ items: MaybeArray<infer U>;
29
+ } ? Array<InferSchema<U>> : T extends {
30
+ additionalItems: MaybeArray<infer U>;
31
+ } ? Array<InferSchema<U>> : unknown[];
32
+ type InferSchema<T> = Pretty<(T extends {
33
+ anyOf: Array<infer U>;
34
+ } ? InferSchema<U> : T extends {
35
+ oneOf: Array<infer U>;
36
+ } ? InferSchema<U> : T extends {
37
+ allOf: Array<infer U>;
38
+ } ? UnionMerge<InferSchema<U>> : T extends {
39
+ schema: infer U;
40
+ } ? InferSchema<U> : T extends {
41
+ type: 'array';
42
+ } ? InferSchemaArray<T> : T extends {
43
+ type: 'object';
44
+ } ? InferSchemaObject<T> : T extends {
45
+ type: 'string';
46
+ } ? T extends {
47
+ enum: Array<infer U>;
48
+ } ? U : string : T extends {
49
+ type: 'integer' | 'number';
50
+ } ? number : T extends {
51
+ type: 'boolean';
52
+ } ? boolean : never) | (T extends {
53
+ nullable: true;
54
+ } ? undefined : never)>;
55
+ /*************************************************************************/
56
+ /*************************************************************************/
57
+ type Parameters<T, I extends string> = UnionMerge<T extends {
58
+ parameters: Array<infer U>;
59
+ } ? U extends {
60
+ in: I;
61
+ name: infer N extends string;
62
+ } ? Record<N, InferSchema<U> | (U extends {
63
+ required: true;
64
+ } ? never : undefined)> : never : never>;
65
+ type RequestBody<T> = Parameters<T, 'body'> extends Record<string, infer U> ? U : never;
66
+ type RequestHeaders<T> = UnionMerge<Parameters<T, 'header'> | Partial<Record<HttpHeader, string | undefined>> | (T extends {
67
+ consumes: Array<infer C>;
68
+ } ? {
69
+ 'Content-Type'?: C;
70
+ } : never)>;
71
+ type RequestData<T> = Pretty<NonNullable<Parameters<T, 'path'>> & NonNullable<Parameters<T, 'query'>> & NonNullable<RequestBody<T>>>;
72
+ type RequestInit<T> = Pretty<Override<globalThis.RequestInit, {
73
+ body?: RequestBody<T>;
74
+ query?: Parameters<T, 'query'>;
75
+ headers?: RequestHeaders<T>;
76
+ parameters?: Parameters<T, 'path'>;
77
+ data?: RequestData<T>;
78
+ }>>;
79
+ /*************************************************************************/
80
+ /*************************************************************************/
81
+ type ResponseBody<T> = T extends {
82
+ responses: Record<200, {
83
+ schema: infer S;
84
+ }>;
85
+ } ? InferSchema<S> : never;
86
+ type Response<T> = T extends {
87
+ responses: infer R;
88
+ } ? ({
89
+ [P in keyof R]: Override<globalThis.Response, {
90
+ status: P extends 'default' ? number : P;
91
+ json: InferSchema<R[P]> extends infer V ? [never] extends V ? never : () => Promise<V> : never;
92
+ }>;
93
+ }) extends infer Result ? Result[keyof Result] : never : never;
94
+ /*************************************************************************/
95
+ /*************************************************************************/
96
+ type OperationId<T> = T extends {
97
+ paths: infer P;
98
+ } ? P extends Record<string, infer R> ? R extends Record<string, infer O> ? O extends {
99
+ operationId: infer N;
100
+ } ? N : string : string : string : string;
101
+ type Route<T> = T extends {
102
+ paths: infer P;
103
+ } ? CollectKey<P> extends Record<string, infer R> ? CollectKey<R> extends Record<string, infer O> ? O extends {
104
+ $key: [infer P extends string, infer M extends string];
105
+ } ? `${Uppercase<M>} ${P}` : string : string : string : string;
106
+ type OperationById<T, U extends OperationId<T>> = T extends {
107
+ paths: infer P;
108
+ } ? CollectKey<P> extends Record<string, infer R> ? CollectKey<R> extends Record<string, infer O> ? O extends {
109
+ $key: [infer P extends string, infer M extends string];
110
+ operationId: U;
111
+ } ? Pretty<{
112
+ method: M;
113
+ path: P;
114
+ } & Omit<O, '$key'>> : never : never : never : never;
115
+ type OperationByRoute<T, U extends Route<T>> = StringSplit<U, ' '> extends [infer M extends string, infer P extends string] ? T extends {
116
+ paths: infer U;
117
+ } ? U extends Record<P, infer R> ? R extends Record<Lowercase<M>, infer O> ? Pretty<{
118
+ method: Lowercase<M>;
119
+ path: P;
120
+ } & O> : never : never : never : never;
121
+ }
122
+
123
+ declare namespace OpenAPIV3 {
124
+ type ServerUrl<T> = T extends {
125
+ servers: Array<{
126
+ url: infer U extends string;
127
+ }>;
128
+ } ? U : string;
129
+ type ServerHeaders<T> = T extends {
130
+ servers: Array<{
131
+ variables: infer V;
132
+ }>;
133
+ } ? V extends {
134
+ [K in keyof V]: {
135
+ enum: Array<infer U>;
136
+ };
137
+ } ? {
138
+ [K in keyof V]: U;
139
+ } : string : never;
140
+ type ServerQuery<T> = T extends {
141
+ components: {
142
+ securitySchemes: {
143
+ api_key: {
144
+ in: 'query';
145
+ name: infer U extends string;
146
+ };
147
+ };
148
+ };
149
+ } ? Partial<Record<U, string>> : never;
150
+ /*************************************************************************/
151
+ /*************************************************************************/
152
+ type RequestBody<T> = T extends {
153
+ requestBody: {
154
+ content: infer C;
155
+ };
156
+ } ? C extends Record<string, {
157
+ schema: infer S;
158
+ }> ? OpenAPIV2.InferSchema<S> : object : object;
159
+ type RequestData<T, U> = Pretty<OpenAPIV2.Parameters<U, 'path'> & OpenAPIV2.Parameters<U, 'query'> & RequestBody<U> & ServerQuery<T>>;
160
+ type RequestInit<T, U> = Pretty<Override<globalThis.RequestInit, {
161
+ body?: RequestBody<U>;
162
+ query?: OpenAPIV2.Parameters<U, 'query'> & ServerQuery<T>;
163
+ headers?: OpenAPIV2.RequestHeaders<U>;
164
+ parameters?: OpenAPIV2.Parameters<U, 'path'>;
165
+ data?: LooseDeep<RequestData<T, U>>;
166
+ }>>;
167
+ /*************************************************************************/
168
+ /*************************************************************************/
169
+ type ResponseBody<U> = U extends {
170
+ responses: Record<200, {
171
+ content: Record<string, {
172
+ schema: infer Schema;
173
+ }>;
174
+ }>;
175
+ } ? OpenAPIV2.InferSchema<Schema> : never;
176
+ type Response<U> = U extends {
177
+ responses: infer Responses;
178
+ } ? ({
179
+ [Status in keyof Responses]: Responses[Status] extends {
180
+ content: Record<'application/json', infer Schema>;
181
+ } ? Pretty<Override<globalThis.Response, {
182
+ status: Status;
183
+ json: OpenAPIV2.InferSchema<Schema> extends infer V ? [never] extends V ? never : () => Promise<V> : never;
184
+ }>> : never;
185
+ }) extends infer Result ? Result[keyof Result] : never : never;
186
+ }
187
+
188
+ export { OpenAPIV2 as O, OpenAPIV3 as a };
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ const methods = ["get", "put", "post", "delete", "options", "head", "patch"];
3
+ function getOperationById(specification, operationId) {
4
+ if (!specification || typeof specification != "object" || specification === null || !("paths" in specification) || typeof specification.paths != "object" || specification.paths === null)
5
+ throw new Error("Missing paths object in the OpenAPI specification.");
6
+ const paths = specification.paths;
7
+ for (const path in paths) {
8
+ const route = paths[path];
9
+ if (!(typeof route != "object" || route === null))
10
+ for (const method of methods) {
11
+ const operation = route[method];
12
+ if (!(!(method in route) || typeof operation != "object" || operation === null || !("operationId" in operation) || operation.operationId !== operationId))
13
+ return { ...route[method], method, path };
14
+ }
15
+ }
16
+ throw new Error(`Operation "${operationId}" not found in specification.`);
17
+ }
18
+ function getBaseUrl(specification) {
19
+ if ("servers" in specification && Array.isArray(specification.servers) && specification.servers.length > 0)
20
+ return specification.servers[0].url;
21
+ if ("host" in specification && typeof specification.host == "string") {
22
+ const scheme = specification.schemes && specification.schemes.length > 0 ? specification.schemes[0] : "https", basePath = specification.basePath && typeof specification.basePath == "string" ? specification.basePath : "/";
23
+ return `${scheme}://${specification.host}${basePath}`;
24
+ }
25
+ throw new Error("No base URL found in the OpenAPI specification.");
26
+ }
27
+ function getOperationByRoute(specification, name) {
28
+ if (!specification || typeof specification != "object" || specification === null || !("paths" in specification) || typeof specification.paths != "object" || specification.paths === null)
29
+ throw new Error("Missing paths object in the OpenAPI specification.");
30
+ const match = /^(get|post|put|patch|delete|head|options) (\/.+)$/i.exec(name);
31
+ if (!match) throw new Error("Could not resolve the path and method from the route name.");
32
+ const [, routeMethod, routePath] = match, method = routeMethod.toLowerCase(), path = specification.paths[routePath];
33
+ if (!path) throw new Error(`Route "${name}" not found in specification.`);
34
+ if (typeof path != "object" || path === null) throw new Error("Invalid path object in the OpenAPI specification.");
35
+ if (!(method in path)) throw new Error(`Method "${method}" not found in path "${routePath}".`);
36
+ return { ...path[method], method, path: routePath };
37
+ }
38
+ function isReferenceObject(value) {
39
+ return typeof value == "object" && value !== null && "$ref" in value && typeof value.$ref == "string";
40
+ }
41
+ function resolveReference(reference, document) {
42
+ if (!isReferenceObject(reference))
43
+ throw new TypeError("Expected value to be an OpenAPI reference object.");
44
+ if (typeof document != "object" || document === null)
45
+ throw new TypeError("Expected OpenAPI specification to be an object.");
46
+ const referenceParts = reference.$ref.replace(/^#\//, "").split("/");
47
+ let result = document;
48
+ for (const part of referenceParts) {
49
+ if (result === void 0 || typeof result != "object" || result === null) break;
50
+ const key = part.replaceAll("~1", "/").replaceAll("~0", "~");
51
+ result = result[key];
52
+ }
53
+ if (result === void 0)
54
+ throw new Error(`Could not resolve OpenAPI component: ${reference.$ref}`);
55
+ return result;
56
+ }
57
+ function resolveDocument(value, document = value) {
58
+ return new Proxy(value, {
59
+ get(target, property) {
60
+ let value2 = target[property];
61
+ return document ? (isReferenceObject(value2) && (value2 = resolveReference(value2, document)), typeof value2 == "object" && value2 !== null ? resolveDocument(value2, document) : value2) : value2;
62
+ }
63
+ });
64
+ }
65
+ exports.getBaseUrl = getBaseUrl;
66
+ exports.getOperationById = getOperationById;
67
+ exports.getOperationByRoute = getOperationByRoute;
68
+ exports.isReferenceObject = isReferenceObject;
69
+ exports.resolveDocument = resolveDocument;
70
+ exports.resolveReference = resolveReference;
71
+ //# sourceMappingURL=BzqHK4CV.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BzqHK4CV.cjs","sources":["../../openapi/getOperationById.ts","../../openapi/getBaseUrl.ts","../../openapi/getOperationByRoute.ts","../../openapi/isReferenceObject.ts","../../openapi/resolveReference.ts","../../openapi/resolveDocument.ts"],"sourcesContent":["import type { OpenAPI } from 'openapi-types'\nimport type { OpenAPIV2 } from './OpenApiV2'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param specification The OpenAPI specification.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example openapiGetOperation(specification, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function getOperationById<T, U extends OpenAPIV2.OperationId<T>>(\n specification: T,\n operationId: U,\n): OpenAPIV2.OperationById<T, U> {\n\n // --- Validate the specification.\n if (!specification\n || typeof specification !== 'object'\n || specification === null\n || 'paths' in specification === false\n || typeof specification.paths !== 'object'\n || specification.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Search for the operation in the specification's paths.\n const paths = specification.paths as OpenAPI.Document['paths']\n for (const path in paths) {\n const route = paths[path]\n if (typeof route !== 'object' || route === null) continue\n\n // --- Search in each method for the operation.\n for (const method of methods) {\n const operation = route[method]\n if (method in route === false\n || typeof operation !== 'object'\n || operation === null\n || 'operationId' in operation === false\n || operation.operationId !== operationId) continue\n\n // --- Route was found, return the operation.\n return { ...route[method], method, path } as OpenAPIV2.OperationById<T, U>\n }\n }\n\n // --- Throw an error if the operation was not found.\n throw new Error(`Operation \"${operationId}\" not found in specification.`)\n}\n","import type { OpenAPI } from 'openapi-types'\n\n/**\n * Given an OpenAPI specification, get the first base URL.\n *\n * @param specification The OpenAPI specification.\n * @returns The first base URL.\n * @example getBaseUrl(specification) // 'https://api.example.com/v1'\n */\nexport function getBaseUrl(specification: OpenAPI.Document): string {\n\n // --- Handle OpenAPI 3.0 specifications.\n if ('servers' in specification && Array.isArray(specification.servers) && specification.servers.length > 0)\n return specification.servers[0].url\n\n // --- Handle OpenAPI 2.0 specifications.\n if ('host' in specification && typeof specification.host === 'string') {\n const scheme = specification.schemes && specification.schemes.length > 0 ? specification.schemes[0] : 'https'\n const basePath = specification.basePath && typeof specification.basePath === 'string' ? specification.basePath : '/'\n return `${scheme}://${specification.host}${basePath}`\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { OpenAPI } from 'openapi-types'\nimport type { OpenAPIV2 } from './OpenApiV2'\n\n/**\n * Given an OpenAPI specification, find a route by its name.\n *\n * @param specification The OpenAPI specification.\n * @param name The name of the route to resolve.\n * @returns The resolved route.\n * @example getOperationByRoute(specification, 'GET /users') // { method: 'get', path: '/users', ... }\n */\nexport function getOperationByRoute<\n T extends object,\n U extends OpenAPIV2.Route<T>,\n>(\n specification: Readonly<T>,\n name: U,\n): OpenAPIV2.OperationByRoute<T, U> {\n\n // --- Assert the specification has a paths object.\n if (!specification\n || typeof specification !== 'object'\n || specification === null\n || 'paths' in specification === false\n || typeof specification.paths !== 'object'\n || specification.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Extract the path and method from the name.\n const match = /^(get|post|put|patch|delete|head|options) (\\/.+)$/i.exec(name)\n if (!match) throw new Error('Could not resolve the path and method from the route name.')\n const [, routeMethod, routePath] = match\n const method = routeMethod.toLowerCase()\n\n // --- Search for the route in the specification's paths.\n const paths = specification.paths as Record<string, OpenAPI.Operation>\n const path = paths[routePath]\n if (!path) throw new Error(`Route \"${name}\" not found in specification.`)\n if (typeof path !== 'object' || path === null) throw new Error('Invalid path object in the OpenAPI specification.')\n if (method in path === false) throw new Error(`Method \"${method}\" not found in path \"${routePath}\".`)\n const operation = path[method as keyof typeof path] as OpenAPI.Operation\n return { ...operation, method, path: routePath } as OpenAPIV2.OperationByRoute<T, U>\n}\n","import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\n\nexport type OpenAPIReference =\n | OpenAPIV2.ReferenceObject\n | OpenAPIV3.ReferenceObject\n | OpenAPIV3_1.ReferenceObject\n\n/**\n * Check if a value is an {@linkcode OpenAPIReference}.\n *\n * @param value The value to check.\n * @returns `true` if the value is a reference object.\n * @example isReferenceObject({ $ref: '#/components/schemas/MySchema' }) // true\n */\nexport function isReferenceObject<T extends OpenAPIReference>(value: unknown): value is T {\n return typeof value === 'object'\n && value !== null\n && '$ref' in value\n && typeof value.$ref === 'string'\n}\n","import type { StringJoin, StringReplace, WriteableDeep } from '@unshared/types'\nimport type { OpenAPIReference } from './isReferenceObject'\nimport { isReferenceObject } from './isReferenceObject'\n\n/**\n * Decode an OpenAPI reference path by replacing the encoded characters with\n * their original values. This function will replace `~0` with `~` and `~1`\n * with `/`.\n *\n * @example DecodeReference<'#/foo~1bar~0baz'> // '#/foo/bar~baz'\n */\nexport type OpenAPIReferenceDecoded<T extends string> =\n StringReplace<StringReplace<T, '~0', '~'>, '~1', '/'>\n\n/**\n * Extract the parts of a reference path as a tuple.\n *\n * @example OpenAPIV3ReferencePath<'#/paths/~1users~1{username}'> // ['paths', '/users/{username}']\n */\nexport type OpenAPIReferencePath<T extends string> =\n T extends `#/${infer P}/${infer Rest}` ? [P, ...OpenAPIReferencePath<Rest>]\n : T extends `#/${infer P}` ? [P]\n : T extends `${infer P}/${infer Rest}` ? [P, ...OpenAPIReferencePath<Rest>]\n : T extends `${infer P}` ? [P]\n : []\n\n/**\n * Resolve a type to the type it references. If the source is not a reference,\n * the source will be returned.\n *\n * @template T The type to resolve.\n * @returns The result type.\n * @example Resolved<{ $ref: '#/info' }, { info: { title: string } }> // { title: string }\n */\nexport type OpenAPIReferenceResolved<\n T extends OpenAPIReference,\n D extends object,\n> =\n D extends object\n ? T extends { $ref: infer R extends string }\n\n // --- Match last part of the reference.\n ? OpenAPIReferencePath<R> extends [infer P extends string]\n ? OpenAPIReferenceDecoded<P> extends keyof D\n ? D[OpenAPIReferenceDecoded<P>] extends object\n ? WriteableDeep<Omit<D[OpenAPIReferenceDecoded<P>], keyof T>>\n : never\n : never\n\n // --- Match middle part of the reference.\n : OpenAPIReferencePath<R> extends [infer P extends string, ...infer Rest extends string[]]\n ? OpenAPIReferenceDecoded<P> extends keyof D\n ? D[OpenAPIReferenceDecoded<P>] extends object\n ? OpenAPIReferenceResolved<{ $ref: StringJoin<Rest, '/'> }, D[OpenAPIReferenceDecoded<P>]>\n : never\n : never\n : never\n : never\n : never\n\n/**\n * Resolve an OpenAPI `ReferenceObject` to the component it references. If the\n * source is not a reference, the source will be returned.\n *\n * @private\n * @param reference The reference object to resolve.\n * @param document The OpenAPI document to resolve the reference from.\n * @returns The result component.\n * @example resolveReference({ $ref: '#/components/schemas/User' }, document)\n */\nexport function resolveReference<\n T extends OpenAPIReference,\n D extends object,\n>(reference: Readonly<T>, document: Readonly<D>): OpenAPIReferenceResolved<T, D> {\n\n // --- Return the source if it is not a reference.\n if (!isReferenceObject(reference))\n throw new TypeError('Expected value to be an OpenAPI reference object.')\n\n // --- Assert that the parameters are valid.\n if (typeof document !== 'object' || document === null)\n throw new TypeError('Expected OpenAPI specification to be an object.')\n\n // --- Resolve the component with it's reference path.\n const referenceParts = reference.$ref.replace(/^#\\//, '').split('/')\n let result = document\n for (const part of referenceParts) {\n if (result === undefined) break\n if (typeof result !== 'object' || result === null) break\n const key = part.replaceAll('~1', '/').replaceAll('~0', '~')\n // @ts-expect-error: assume the part is a key of the object.\n result = result[key] as unknown\n }\n\n // --- Throw an error if the component could not be result.\n if (result === undefined)\n throw new Error(`Could not resolve OpenAPI component: ${reference.$ref}`)\n\n // --- Return the result component.\n return result as OpenAPIReferenceResolved<T, D>\n}\n","import type { ObjectLike } from '@unshared/types'\nimport type { OpenAPIReference } from './isReferenceObject'\nimport type { OpenAPIReferenceResolved } from './resolveReference'\nimport { isReferenceObject } from './isReferenceObject'\nimport { resolveReference as resolveReference } from './resolveReference'\n\n/**\n * Resolve a type to the type it references. If the source is not a reference,\n * the source will be returned.\n *\n * @template T The type to resolve.\n * @returns The resolved type.\n * @example\n * type Resolved = OpenAPIResolved<{\n * ...\n * paths: {\n * '/users': {\n * get: { $ref: '#/components/routes/getUsers' }\n * }\n * }\n * }>\n */\nexport type OpenAPIResolved<T, D = T> =\n T extends OpenAPIReference\n ? D extends object ? OpenAPIResolved<OpenAPIReferenceResolved<T, D>, D> : never\n : T extends object ? { -readonly [K in keyof T]: OpenAPIResolved<T[K], D> } : T\n\n/**\n * Recursively resolve all references in an OpenAPI specification. This function\n * will return a `Proxy` object that will resolve references on the fly.\n *\n * @param value The OpenAPI specification.\n * @returns The resolved OpenAPI specification.\n * @example\n * const resolved = resolveReferences({\n * ...\n * paths: {\n * '/users': {\n * get: { $ref: '#/components/routes/getUsers' },\n * },\n * },\n * })\n */\nexport function resolveDocument<T extends object>(value: Readonly<T>): OpenAPIResolved<T>\nexport function resolveDocument<T extends object, D>(value: Readonly<T>, document: Readonly<D>): OpenAPIResolved<T, D>\nexport function resolveDocument(value: Readonly<ObjectLike>, document = value): unknown {\n return new Proxy(value, {\n get(target, property: string) {\n let value = target[property]\n\n // --- Abort if no document is provided.\n if (!document) return value\n\n // --- Resolve the reference if it is a reference object.\n if (isReferenceObject(value))\n value = resolveReference(value, document)\n\n // --- Recursively resolve references in objects.\n if (typeof value === 'object' && value !== null)\n return resolveDocument(value as ObjectLike, document)\n\n // --- Return the value as is.\n return value\n },\n })\n}\n"],"names":["value"],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ function isFormDataLike(value) {
3
+ return typeof value != "object" || value === null ? !1 : value instanceof FormData ? !0 : Object.values(value).some((x) => x instanceof File ? !0 : Array.isArray(x) ? x.some((item) => item instanceof File) : x instanceof Blob);
4
+ }
5
+ function isObjectLike(value) {
6
+ return typeof value == "object" && value !== null && value.constructor === Object;
7
+ }
8
+ function toFormData(object) {
9
+ if (object instanceof FormData) return object;
10
+ const formData = new FormData();
11
+ for (const key in object) {
12
+ const value = object[key];
13
+ if (value !== void 0)
14
+ if (Array.isArray(value))
15
+ for (const item of value)
16
+ formData.append(key, item);
17
+ else
18
+ formData.append(key, value);
19
+ }
20
+ return formData;
21
+ }
22
+ function parseRequestBody(route, options, context) {
23
+ const { data, body } = options, { init } = context;
24
+ if (init.headers = init.headers ?? {}, body !== void 0) {
25
+ init.body = body;
26
+ return;
27
+ }
28
+ ["get", "head", "delete"].includes(init.method ?? "get") || data != null && (isFormDataLike(data) ? (init.body = toFormData(data), init.headers = { ...init.headers, "Content-Type": "multipart/form-data" }) : data instanceof ReadableStream ? init.body = data : data instanceof File ? (init.body = data.stream(), init.headers = { ...init.headers, "Content-Type": "application/octet-stream" }) : isObjectLike(data) && (init.body = JSON.stringify(data), init.headers = { ...init.headers, "Content-Type": "application/json" }));
29
+ }
30
+ function parseRequestHeaders(route, options, context) {
31
+ const { headers } = options, { init } = context;
32
+ if (init.headers = init.headers ?? {}, !!headers)
33
+ for (const key in headers) {
34
+ const value = headers[key];
35
+ value !== void 0 && typeof value == "string" && (init.headers = { ...init.headers, [key]: value });
36
+ }
37
+ }
38
+ const EXP_PATH_PARAMETER = /:([\w-]+)|%7B([\w-]+)%7D/g;
39
+ function parseRequestParameters(route, options, context) {
40
+ const { url } = context, { data, parameters = {} } = options;
41
+ if (!url) throw new Error("Could not resolve the `RequestInit` object: the `url` is missing.");
42
+ const pathParameters = url.pathname.match(EXP_PATH_PARAMETER);
43
+ if (pathParameters) {
44
+ if (isObjectLike(data))
45
+ for (const key in data) {
46
+ const value = data[key];
47
+ value !== void 0 && typeof value == "string" && parameters[key] === void 0 && (parameters[key] = value, delete data[key]);
48
+ }
49
+ for (const parameter of pathParameters.values()) {
50
+ const key = parameter.replaceAll(EXP_PATH_PARAMETER, "$1$2"), value = parameters[key];
51
+ value !== void 0 && typeof value == "string" && (url.pathname = url.pathname.replace(parameter, value));
52
+ }
53
+ }
54
+ }
55
+ function toSearchParams(object, options = {}) {
56
+ const { searchArrayFormat = "flat" } = options, search = new URLSearchParams();
57
+ for (const key in object) {
58
+ const value = object[key];
59
+ if (value !== void 0)
60
+ if (Array.isArray(value)) {
61
+ if (searchArrayFormat === "brackets") for (const v of value) search.append(`${key}[]`, String(v));
62
+ else if (searchArrayFormat === "indices") for (const [i, v] of value.entries()) search.append(`${key}[${i}]`, String(v));
63
+ else if (searchArrayFormat === "comma") search.append(key, value.join(","));
64
+ else if (searchArrayFormat === "path") for (const [i, v] of value.entries()) search.append(`${key}.${i}`, String(v));
65
+ else if (searchArrayFormat === "flat") for (const v of value) search.append(key, String(v));
66
+ } else
67
+ search.append(key, value.toString());
68
+ }
69
+ return search;
70
+ }
71
+ function parseRequestQuery(route, options, context) {
72
+ const { url, init } = context, { data, query = {}, searchArrayFormat } = options;
73
+ if (!url) throw new Error("Could not resolve the `RequestInit` object: the `url` is missing.");
74
+ if (!["post", "put", "patch"].includes(init.method ?? "get") && isObjectLike(data))
75
+ for (const key in data)
76
+ data[key] !== void 0 && query[key] === void 0 && (query[key] = data[key], delete data[key]);
77
+ url.search = toSearchParams(query, { searchArrayFormat }).toString();
78
+ }
79
+ const EXP_REQUEST = /^((?<method>[a-z]+) )?(?<url>[^:]+?:\/{2}[^/]+)?(?<path>\/[^\s?]*)/i, METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "head", "options"]);
80
+ function parseRequestUrl(route, options, context) {
81
+ const { method, baseUrl } = options, match = EXP_REQUEST.exec(route);
82
+ if (!match?.groups) throw new Error("Could not resolve the `RequestInit` object: Invalid route name.");
83
+ const routeMethod = method ?? match.groups.method ?? "get", routeBaseUrl = baseUrl ?? match.groups.url;
84
+ if (!routeBaseUrl) throw new Error("Could not resolve the `RequestInit` object: the `baseUrl` is missing.");
85
+ const methodLower = routeMethod.toLowerCase();
86
+ if (!METHODS.has(methodLower)) throw new Error(`Could not resolve the \`RequestInit\` object:, the method \`${routeMethod}\` is invalid.`);
87
+ context.init = context.init ?? {}, context.init.method = methodLower, context.url = new URL(routeBaseUrl), context.url.pathname += context.url.pathname.endsWith("/") ? match.groups.path.slice(1) : match.groups.path;
88
+ }
89
+ function parseRequest(route, options = {}) {
90
+ const { data, body, query, headers, parameters, baseUrl, method, searchArrayFormat, ...requestInit } = options, context = { init: requestInit };
91
+ return parseRequestUrl(route, { baseUrl, method }, context), parseRequestParameters(route, { data, parameters }, context), parseRequestQuery(route, { data, query, searchArrayFormat }, context), parseRequestBody(route, { body, data }, context), parseRequestHeaders(route, { headers }, context), context;
92
+ }
93
+ exports.isFormDataLike = isFormDataLike;
94
+ exports.isObjectLike = isObjectLike;
95
+ exports.parseRequest = parseRequest;
96
+ exports.parseRequestBody = parseRequestBody;
97
+ exports.parseRequestHeaders = parseRequestHeaders;
98
+ exports.parseRequestParameters = parseRequestParameters;
99
+ exports.parseRequestQuery = parseRequestQuery;
100
+ exports.parseRequestUrl = parseRequestUrl;
101
+ exports.toFormData = toFormData;
102
+ exports.toSearchParams = toSearchParams;
103
+ //# sourceMappingURL=C3RyfPUw.cjs.map