@unshared/client 0.3.0 → 0.3.2

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.
Files changed (48) hide show
  1. package/dist/chunks/0ZzUT3m_.js +46 -0
  2. package/dist/chunks/0ZzUT3m_.js.map +1 -0
  3. package/dist/chunks/6IxvRpmY.js +86 -0
  4. package/dist/chunks/6IxvRpmY.js.map +1 -0
  5. package/dist/chunks/BMbsYNBd.cjs +84 -0
  6. package/dist/chunks/BMbsYNBd.cjs.map +1 -0
  7. package/dist/chunks/{D51s1VII.js → BUeqbyph.js} +3 -45
  8. package/dist/chunks/BUeqbyph.js.map +1 -0
  9. package/dist/chunks/Biic1J5b.js.map +1 -1
  10. package/dist/chunks/{B92aAMq0.d.ts → CO11DuYE.d.ts} +1 -1
  11. package/dist/chunks/CYmaYL5B.cjs +45 -0
  12. package/dist/chunks/CYmaYL5B.cjs.map +1 -0
  13. package/dist/chunks/{CfKxYeRr.cjs → Cayg8606.cjs} +4 -47
  14. package/dist/chunks/Cayg8606.cjs.map +1 -0
  15. package/dist/chunks/CtW2aMuA.cjs.map +1 -1
  16. package/dist/chunks/{lMH6B5BV.js → DJJsADWD.js} +2 -2
  17. package/dist/chunks/{lMH6B5BV.js.map → DJJsADWD.js.map} +1 -1
  18. package/dist/chunks/{iA98-4f5.cjs → Du_W5H6e.cjs} +2 -2
  19. package/dist/chunks/{iA98-4f5.cjs.map → Du_W5H6e.cjs.map} +1 -1
  20. package/dist/chunks/{CjU0376e.d.ts → mHfUAX_g.d.ts} +18 -23
  21. package/dist/createClient.cjs +17 -15
  22. package/dist/createClient.cjs.map +1 -1
  23. package/dist/createClient.d.ts +44 -27
  24. package/dist/createClient.js +19 -16
  25. package/dist/createClient.js.map +1 -1
  26. package/dist/createService.cjs +2 -1
  27. package/dist/createService.cjs.map +1 -1
  28. package/dist/createService.d.ts +2 -2
  29. package/dist/createService.js +2 -1
  30. package/dist/createService.js.map +1 -1
  31. package/dist/index.cjs +7 -22
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.ts +5 -6
  34. package/dist/index.js +7 -25
  35. package/dist/index.js.map +1 -1
  36. package/dist/openapi.d.ts +2 -2
  37. package/dist/utils.cjs +4 -4
  38. package/dist/utils.d.ts +2 -2
  39. package/dist/utils.js +7 -6
  40. package/dist/utils.js.map +1 -1
  41. package/dist/websocket.cjs +8 -0
  42. package/dist/websocket.cjs.map +1 -0
  43. package/dist/websocket.d.ts +143 -0
  44. package/dist/websocket.js +9 -0
  45. package/dist/websocket.js.map +1 -0
  46. package/package.json +9 -4
  47. package/dist/chunks/CfKxYeRr.cjs.map +0 -1
  48. package/dist/chunks/D51s1VII.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var awaitable = require("@unshared/functions/awaitable");
2
+ var parseRequestQuery = require("./CYmaYL5B.cjs"), awaitable = require("@unshared/functions/awaitable");
3
3
  function isObjectLike(value) {
4
4
  return typeof value == "object" && value !== null && value.constructor === Object;
5
5
  }
@@ -34,46 +34,6 @@ function parseRequestHeaders(context, options) {
34
34
  (typeof value != "string" || value.length === 0) && typeof value != "number" || (context.init = context.init ?? {}, context.init.headers = context.init.headers ?? {}, context.init.headers = { ...context.init.headers, [key]: String(value) });
35
35
  }
36
36
  }
37
- const EXP_PATH_PARAMETER = /:([\w-]+)|%7B([\w-]+)%7D/g;
38
- function parseRequestParameters(context, options) {
39
- const { url } = context, { parameters } = options;
40
- if (typeof parameters != "object" || parameters === null || url === void 0) return;
41
- if (!(url instanceof URL)) throw new Error("The `url` must be an instance of `URL`.");
42
- const pathParameters = url.pathname.match(EXP_PATH_PARAMETER);
43
- if (pathParameters)
44
- for (const parameter of pathParameters.values()) {
45
- const key = parameter.replaceAll(EXP_PATH_PARAMETER, "$1$2"), value = parameters[key];
46
- (typeof value == "string" && value.length > 0 || typeof value == "number" && Number.isFinite(value) || typeof value == "boolean") && (url.pathname = url.pathname.replace(parameter, value.toString()), delete parameters[key]);
47
- }
48
- }
49
- function toSearchParams(object, options = {}) {
50
- const { format = "flat" } = options, search = new URLSearchParams();
51
- for (const key in object) {
52
- const value = object[key];
53
- if (value !== void 0)
54
- if (Array.isArray(value)) {
55
- if (format === "brackets") for (const v of value) search.append(`${key}[]`, String(v));
56
- else if (format === "indices") for (const [i, v] of value.entries()) search.append(`${key}[${i}]`, String(v));
57
- else if (format === "comma") search.append(key, value.join(","));
58
- else if (format === "path") for (const [i, v] of value.entries()) search.append(`${key}.${i}`, String(v));
59
- else if (format === "flat") for (const v of value) search.append(key, String(v));
60
- } else
61
- search.append(key, value.toString());
62
- }
63
- return search;
64
- }
65
- function parseRequestQuery(context, options) {
66
- const { url } = context, { query, queryArrayFormat } = options;
67
- if (url === void 0) return;
68
- if (!(url instanceof URL)) throw new Error("The `url` must be an instance of `URL.");
69
- if (typeof query != "object" || query === null) return;
70
- const queryObject = {};
71
- for (const key in query) {
72
- const value = query[key];
73
- (typeof value == "string" && value.length > 0 || typeof value == "number" && Number.isFinite(value) || typeof value == "boolean" || Array.isArray(value) && value.length > 0 && value.every((v) => typeof v == "string" || typeof v == "number" || typeof v == "boolean")) && (queryObject[key] = value, delete query[key]);
74
- }
75
- url.search = toSearchParams(queryObject, { format: queryArrayFormat }).toString();
76
- }
77
37
  const EXP_REQUEST = /^((?<method>[a-z]+) )?(?<url>[^:]+?:\/{2}[^/]+)?(?<path>\/[^\s?]*)/i, METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "head", "options"]);
78
38
  function parseRequestUrl(context, route, options) {
79
39
  const { method, baseUrl } = options, match = EXP_REQUEST.exec(route);
@@ -86,9 +46,9 @@ function parseRequestUrl(context, route, options) {
86
46
  }
87
47
  function parseRequest(route, options = {}) {
88
48
  const { data, body, query, parameters, headers, method, baseUrl, queryArrayFormat, ...init } = options, context = { init }, dataObject = isObjectLike(data) ? data : void 0;
89
- parseRequestUrl(context, route, { baseUrl, method }), parseRequestParameters(context, { parameters: parameters ?? dataObject });
49
+ parseRequestUrl(context, route, { baseUrl, method }), parseRequestQuery.parseRequestParameters(context, { parameters: parameters ?? dataObject });
90
50
  const requestMethod = context.init?.method?.toLowerCase() ?? "get", requestExpectsBody = ["post", "put", "patch"].includes(requestMethod);
91
- return parseRequestQuery(context, { queryArrayFormat, query: requestExpectsBody ? query : query ?? dataObject }), parseRequestBody(context, { body: requestExpectsBody ? body ?? dataObject : void 0 }), parseRequestHeaders(context, { headers }), context;
51
+ return parseRequestQuery.parseRequestQuery(context, { queryArrayFormat, query: requestExpectsBody ? query : query ?? dataObject }), parseRequestBody(context, { body: requestExpectsBody ? body ?? dataObject : void 0 }), parseRequestHeaders(context, { headers }), context;
92
52
  }
93
53
  async function fetch(route, options = {}) {
94
54
  const { url, init } = parseRequest(route, options);
@@ -147,9 +107,6 @@ exports.isObjectLike = isObjectLike;
147
107
  exports.parseRequest = parseRequest;
148
108
  exports.parseRequestBody = parseRequestBody;
149
109
  exports.parseRequestHeaders = parseRequestHeaders;
150
- exports.parseRequestParameters = parseRequestParameters;
151
- exports.parseRequestQuery = parseRequestQuery;
152
110
  exports.parseRequestUrl = parseRequestUrl;
153
111
  exports.toFormData = toFormData;
154
- exports.toSearchParams = toSearchParams;
155
- //# sourceMappingURL=CfKxYeRr.cjs.map
112
+ //# sourceMappingURL=Cayg8606.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Cayg8606.cjs","sources":["../../utils/isObjectLike.ts","../../utils/isFormDataLike.ts","../../utils/toFormData.ts","../../utils/parseRequestBody.ts","../../utils/parseRequestHeaders.ts","../../utils/parseRequestUrl.ts","../../utils/parseRequest.ts","../../utils/fetch.ts","../../utils/handleResponseStreamJson.ts","../../utils/handleResponse.ts"],"sourcesContent":["import type { ObjectLike } from '@unshared/types'\n\n/**\n * Predicate to check if a value is an object-like value.\n *\n * @param value The value to check.\n * @returns `true` if the value is an object-like value, `false` otherwise.\n * @example isObjectLike({}) // true\n */\nexport function isObjectLike(value: unknown): value is ObjectLike {\n return typeof value === 'object' && value !== null && value.constructor === Object\n}\n","/**\n * A type that represents a FormData-like object, which is a plain object with\n * nested Blob, File, or FileList values. Or a FormData instance.\n */\nexport type FormDataLike = FormData | Record<string, Blob | File | FileList>\n\n/**\n * Predicate to check if a value is FormData-like, meaning it is a plain object\n * with nested Blob, File, or FileList values.\n *\n * @param value The value to check.\n * @returns `true` if the value is FormData-like, `false` otherwise.\n * @example isFormDataLike({ file: new File(['test'], 'test.txt') }) // true\n */\nexport function isFormDataLike(value: unknown): value is FormDataLike {\n if (typeof value !== 'object' || value === null) return false\n if (value instanceof FormData) return true\n const values = Object.values(value)\n if (values.length === 0) return false\n return values.every((x) => {\n if (x instanceof File) return true\n if (Array.isArray(x)) return x.every(item => item instanceof File)\n return x instanceof Blob\n })\n}\n","import type { FormDataLike } from './isFormDataLike'\n\n/**\n * Casts an object that may contain `Blob`, `File`, or `FileList` values to a `FormData` object.\n *\n * @param object The object to cast to a `FormData` object.\n * @returns The `FormData` object.\n */\nexport function toFormData(object: FormDataLike): FormData {\n if (object instanceof FormData) return object\n const formData = new FormData()\n for (const key in object) {\n const value = object[key]\n if (value === undefined) continue\n if (Array.isArray(value)) {\n for (const item of value)\n formData.append(key, item as Blob | string)\n }\n else {\n formData.append(key, value as Blob | string)\n }\n }\n return formData\n}\n","import type { FetchOptions, RequestContext } from './parseRequest'\nimport { isFormDataLike } from './isFormDataLike'\nimport { isObjectLike } from './isObjectLike'\nimport { toFormData } from './toFormData'\n\n/**\n * Parse the request body based on the provided data and options.\n *\n * @param context The request context.\n * @param options The request options.\n */\nexport function parseRequestBody(context: RequestContext, options: FetchOptions): void {\n const { body } = options\n\n // --- If the method is `GET`, `HEAD`, or `DELETE`, return early.\n if (!context.init?.method) return\n if (['get', 'head', 'delete'].includes(context.init.method ?? 'get')) return\n\n // --- If no data is provided, return early.\n if (body === null || body === undefined) return\n\n // --- If data contains a `File` object, create a FormData object.\n if (isFormDataLike(body)) {\n context.init.body = toFormData(body)\n context.init.headers = context.init.headers ?? {}\n context.init.headers = { ...context.init.headers, 'Content-Type': 'multipart/form-data' }\n }\n\n // --- If the data is a `ReadableStream`, pass it directly to the body.\n else if (body instanceof ReadableStream) {\n context.init.body = body\n context.init.headers = context.init.headers ?? {}\n context.init.headers = { ...context.init.headers, 'Content-Type': 'application/octet-stream' }\n }\n\n // --- If the data is a Blob, pass it directly to the body.\n else if (body instanceof File) {\n context.init.body = body.stream()\n context.init.headers = context.init.headers ?? {}\n context.init.headers = { ...context.init.headers, 'Content-Type': 'application/octet-stream' }\n }\n\n // --- Otherwise, stringify the data and set the content type to JSON.\n else if (isObjectLike(body)) {\n context.init.body = JSON.stringify(body)\n context.init.headers = context.init.headers ?? {}\n context.init.headers = { ...context.init.headers, 'Content-Type': 'application/json' }\n }\n\n // --- For all other data types, set the body directly.\n else {\n context.init.body = body as BodyInit\n }\n}\n","import type { FetchOptions, RequestContext } from './parseRequest'\n\n/**\n * Parse the request headers based on the provided data and options.\n *\n * @param context The request context.\n * @param options The request options.\n * @example\n *\n * // Append the `Content-Type` header to the request.\n * const context = {}\n * parseRequestHeaders(context, { headers: { 'Content-Type': 'application/json' } })\n *\n * // Will mutate the `init` object to include the headers.\n * console.log(context) // => { init: { headers: { 'Content-Type': 'application/json' } } }\n */\nexport function parseRequestHeaders(context: RequestContext, options: FetchOptions): void {\n const { headers } = options\n\n // --- Merge the headers with the existing headers.\n for (const key in headers) {\n const value = headers[key]\n if (((typeof value !== 'string' || value.length === 0) && typeof value !== 'number')) continue\n context.init = context.init ?? {}\n context.init.headers = context.init.headers ?? {}\n context.init.headers = { ...context.init.headers, [key]: String(value) }\n }\n}\n","import type { FetchOptions, RequestContext } from './parseRequest'\n\n/** Regular expression to match the request method and URL. */\nconst EXP_REQUEST = /^((?<method>[a-z]+) )?(?<url>[^:]+?:\\/{2}[^/]+)?(?<path>\\/[^\\s?]*)/i\n\n/** Valid HTTP methods. */\nconst METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'options'])\n\n/**\n * Parses the route name to extract the URL and method. It allows the url and method to be\n * provided in the route name, or in the options object. The method will default to 'get'.\n *\n * @param context The request context to mutate.\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @example parseRequestUrl('GET /users', { baseUrl: 'https://api.example.com' }, context)\n */\nexport function parseRequestUrl(context: RequestContext, route: string, options: FetchOptions): void {\n const { method, baseUrl } = options\n\n // --- Extract the path, method, and base URL from the route name.\n const match = EXP_REQUEST.exec(route)\n if (!match?.groups) throw new Error('Could not resolve the `RequestInit` object: Invalid route name.')\n const routeMethod = method ?? match.groups.method ?? 'get'\n const routeBaseUrl = baseUrl ?? match.groups.url\n\n // --- Assert the base URL is provided, either in the options or the route name.\n if (!routeBaseUrl) throw new Error('Could not resolve the `RequestInit` object: the `baseUrl` is missing.')\n\n // --- Assert the method is valid.\n const methodLower = routeMethod.toLowerCase()\n const methodIsValid = METHODS.has(methodLower)\n if (!methodIsValid) throw new Error(`Could not resolve the \\`RequestInit\\` object:, the method \\`${routeMethod}\\` is invalid.`)\n\n // --- Create the url and apply the method.\n context.init = context.init ?? {}\n context.init.method = methodLower\n context.url = new URL(routeBaseUrl)\n\n // --- Append the path to the URL while making sure there are no double slashes.\n context.url.pathname += context.url.pathname.endsWith('/') ? match.groups.path.slice(1) : match.groups.path\n}\n","import type { Loose, MaybeLiteral, ObjectLike } from '@unshared/types'\nimport type { UnionMerge } from '@unshared/types'\nimport type { HttpHeader } from '../HttpHeaders'\nimport type { HttpMethod } from '../HttpMethods'\nimport type { SearchArrayFormat } from './toSearchParams'\nimport { isObjectLike } from './isObjectLike'\nimport { parseRequestBody } from './parseRequestBody'\nimport { parseRequestHeaders } from './parseRequestHeaders'\nimport { parseRequestParameters } from './parseRequestParameters'\nimport { parseRequestQuery } from './parseRequestQuery'\nimport { parseRequestUrl } from './parseRequestUrl'\n\n/** The methods to use for the request. */\nexport type FetchMethod = Lowercase<keyof typeof HttpMethod> | Uppercase<keyof typeof HttpMethod>\n\n/** Headers to include in the request. */\nexport type FetchHeaders = Partial<Record<MaybeLiteral<HttpHeader>, number | string>>\n\n/** Options to pass to the request. */\nexport interface FetchOptions<\n Method extends FetchMethod = FetchMethod,\n BaseUrl extends string = string,\n Parameters extends ObjectLike = ObjectLike,\n Query extends ObjectLike = ObjectLike,\n Body = unknown,\n Headers extends ObjectLike = ObjectLike,\n> extends Omit<RequestInit, 'body' | 'headers' | 'method'> {\n\n /**\n * The method to use for the request.\n *\n * @example 'GET'\n */\n method?: Method\n\n /**\n * The base URL to use for the request. This URL will be used to resolve the\n * path and query parameters of the request.\n *\n * @example 'https://api.example.com'\n */\n baseUrl?: BaseUrl\n\n /**\n * The data to include in the request. This data will be used to populate the\n * query parameters, body, and headers of the request based on the method type.\n *\n * @example { id: 1 }\n */\n data?: Loose<UnionMerge<Body | Headers | Query>>\n\n /**\n * The path parameters to include in the request.\n */\n parameters?: Parameters\n\n /**\n * The query parameters to include in the request.\n */\n query?: Loose<Query>\n\n /**\n * The format to use when serializing the query parameters.\n */\n queryArrayFormat?: SearchArrayFormat\n\n /**\n * The body to include in the request.\n */\n body?: Body extends ObjectLike ? Loose<Body> : Body\n\n /**\n * The headers to include in the request.\n */\n headers?: FetchHeaders & Headers\n}\n\nexport interface RequestContext {\n url?: URL\n init?: RequestInit\n}\n\n/**\n * Resolves the request body and/or query parameters based on the method type. This function\n * will mutate the `init` object to include the request body and headers based on the data type.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The URL and the `RequestInit` object.\n */\nexport function parseRequest(route: string, options: FetchOptions = {}): RequestContext {\n const { data, body, query, parameters, headers, method, baseUrl, queryArrayFormat, ...init } = options\n const context: RequestContext = { init }\n const dataObject = isObjectLike(data) ? data : undefined\n\n // --- Parse the URL and insert the path parameters.\n parseRequestUrl(context, route, { baseUrl, method })\n parseRequestParameters(context, { parameters: parameters ?? dataObject })\n\n // --- Depending on the method, parse the query, body, and headers.\n const requestMethod = context.init?.method?.toLowerCase() ?? 'get'\n const requestExpectsBody = ['post', 'put', 'patch'].includes(requestMethod)\n parseRequestQuery(context, { queryArrayFormat, query: requestExpectsBody ? query : query ?? dataObject })\n parseRequestBody(context, { body: requestExpectsBody ? body ?? dataObject : undefined })\n parseRequestHeaders(context, { headers })\n\n // --- Return the context with the URL and the `RequestInit` object.\n return context\n}\n","import type { FetchOptions } from './parseRequest'\nimport { parseRequest } from './parseRequest'\n\n/**\n * Fetch a route with the provided options. This function will parse the route and\n * options to create a `Request` object and return the response from the server.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The response from the server.\n * @example fetch('GET /users', { query: { limit: 10 } })\n */\nexport async function fetch(route: string, options?: FetchOptions): Promise<Response>\nexport async function fetch(route: string, options: FetchOptions = {}): Promise<Response> {\n const { url, init } = parseRequest(route, options)\n if (!url) throw new Error('Could not parse request URL')\n return await globalThis.fetch(url, init)\n}\n","import type { Awaitable } from '@unshared/functions/awaitable'\nimport type { RequestOptions } from './request'\nimport { awaitable } from '@unshared/functions/awaitable'\n\nasync function * createResponseStreamJsonIterator(response: Response, options: RequestOptions): AsyncGenerator<unknown, void, unknown> {\n const { onError, onSuccess, onData, onEnd } = options\n try {\n const body = response.body\n if (body === null) throw new Error('Could not read the response body, it is empty.')\n const reader = body.getReader()\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n const parts = new TextDecoder().decode(value).trim().split('\\0').filter(Boolean)\n\n // --- For each part, parse as JSON and yield the data.\n for (const part of parts) {\n const payload = JSON.parse(part) as unknown\n if (onData) onData(payload)\n yield payload\n }\n }\n if (onSuccess) onSuccess(response)\n }\n catch (error) {\n if (onError) onError(error as Error)\n }\n finally {\n if (onEnd) onEnd(response)\n }\n}\n\n/**\n * Handle a request response where the content type is a stream of JSON objects. This function\n * will parse the JSON objects and yield the data to the caller. If an error occurs, the `onError`\n * callback will be called and the function will return.\n *\n * @param response The response to handle.\n * @param options The options to pass to the request.\n * @returns An awaitable iterator that yields the parsed JSON objects.\n */\nexport function handleResponseStreamJson(response: Response, options: RequestOptions): Awaitable<AsyncIterable<unknown>, unknown[]> {\n const responseIterator = createResponseStreamJsonIterator(response, options)\n return awaitable(responseIterator)\n}\n","import type { RequestOptions } from './request'\nimport { handleResponseStreamJson } from './handleResponseStreamJson'\n\n/**\n * Handle a request response. This function will parse the response based on the content type and\n * return the data. If an error occurs, the `onError` callback will be called and the function will\n * throw an error.\n *\n * @param response The response to handle.\n * @param options The options to pass to the request.\n * @returns The parsed data from the response.\n */\nexport async function handleResponse(response: Response, options: RequestOptions = {}): Promise<unknown> {\n const { onError, onSuccess, onData, onEnd, onFailure } = options\n const contentType = response.headers.get('Content-Type')\n\n // --- If the response is not OK, throw an error with the response message.\n if (!response.ok) {\n if (onFailure) onFailure(response)\n if (onEnd) onEnd(response)\n throw new Error(response.statusText)\n }\n\n // --- If the status code is 204, return an empty response early.\n if (response.status === 204) {\n if (onSuccess) onSuccess(response)\n if (onEnd) onEnd(response)\n return\n }\n\n // --- If the response is a text content type, return the text response.\n if (contentType?.startsWith('text/')) {\n return await response.text()\n .then((data) => {\n if (onData) onData(data)\n if (onSuccess) onSuccess(response)\n return data\n })\n .catch((error: Error) => {\n if (onError) onError(error)\n throw error\n })\n .finally(() => {\n if (onEnd) onEnd(response)\n })\n }\n\n // --- If the response is a application/json, parse the JSON and return it.\n if (contentType === 'application/json') {\n return await response.json()\n .then((data) => {\n if (onData) onData(data)\n if (onSuccess) onSuccess(response)\n return data as unknown\n })\n .catch((error: Error) => {\n if (onError) onError(error)\n throw error\n })\n .finally(() => {\n if (onEnd) onEnd(response)\n })\n }\n\n // --- If the response is a application/stream+json, return an iterator that parses the JSON.\n if (contentType === 'application/stream+json')\n return handleResponseStreamJson(response, options)\n\n // --- Otherwise, fallback to returning the response body as-is.\n if (onSuccess) onSuccess(response)\n if (onEnd) onEnd(response)\n return response.body\n}\n"],"names":["parseRequestParameters","parseRequestQuery","awaitable"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CtW2aMuA.cjs","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\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 getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\nT extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = { method: FetchMethod; path: string } & OpenAPI.Operation\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<{ method: M; path: P } & Omit<O, '$key'>>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U> {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.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 = document.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 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"],"names":[],"mappings":";AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACf,UAAA,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AAClC,WAAA,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EAAA;AAG/C,QAAA,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAqC3D,SAAA,iBAA8C,UAAa,aAAqC;AAG9G,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAW,WAAA,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AAChB,UAAA,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AAClB,UAAA,QAAQ,MAAM,IAAI;AACpB,QAAA,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AACtB,cAAA,YAAY,MAAM,MAAM;AAC1B,YAAA,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAK;AAAA,MAAA;AAAA,EAC1C;AAIF,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;;;"}
1
+ {"version":3,"file":"CtW2aMuA.cjs","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\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 getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\nT extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = OpenAPI.Operation & { method: FetchMethod; path: string }\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<Omit<O, '$key'> & { method: M; path: P }>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U> {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.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 = document.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 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"],"names":[],"mappings":";AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACf,UAAA,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AAClC,WAAA,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EAAA;AAG/C,QAAA,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAqC3D,SAAA,iBAA8C,UAAa,aAAqC;AAG9G,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAW,WAAA,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AAChB,UAAA,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AAClB,UAAA,QAAQ,MAAM,IAAI;AACpB,QAAA,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AACtB,cAAA,YAAY,MAAM,MAAM;AAC1B,YAAA,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAK;AAAA,MAAA;AAAA,EAC1C;AAIF,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;;;"}
@@ -1,4 +1,4 @@
1
- import { f as fetch, h as handleResponse } from "./D51s1VII.js";
1
+ import { f as fetch, h as handleResponse } from "./BUeqbyph.js";
2
2
  async function request(route, options = {}) {
3
3
  const response = await fetch(route, options);
4
4
  return await handleResponse(response, options);
@@ -6,4 +6,4 @@ async function request(route, options = {}) {
6
6
  export {
7
7
  request as r
8
8
  };
9
- //# sourceMappingURL=lMH6B5BV.js.map
9
+ //# sourceMappingURL=DJJsADWD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lMH6B5BV.js","sources":["../../utils/request.ts"],"sourcesContent":["import type { ObjectLike } from '@unshared/types'\nimport type { FetchMethod, FetchOptions } from './parseRequest'\nimport { fetch } from './fetch'\nimport { handleResponse } from './handleResponse'\n\nexport interface RequestOptions<\n Method extends FetchMethod = FetchMethod,\n BaseUrl extends string = string,\n Parameters extends ObjectLike = ObjectLike,\n Query extends ObjectLike = ObjectLike,\n Body = unknown,\n Headers extends ObjectLike = ObjectLike,\n Data = any,\n Response = globalThis.Response,\n> extends\n FetchOptions<Method, BaseUrl, Parameters, Query, Body, Headers> {\n\n /**\n * The callback that is called when an error occurs during the request.\n */\n onError?: (error: Error) => any\n\n /**\n * The callback that is called when data is received from the request. This callback\n * will be called for each chunk of data that is received from the request.\n */\n onData?: (data: Data) => any\n\n /**\n * The callback that is called when the request is successful. This callback will be\n * called after the request is complete and all data has been received.\n */\n onSuccess?: (response: Response) => any\n\n /**\n * The callback that is called when the status code is not OK. This callback will be called\n * after the request is complete and before the data is consumed.\n */\n onFailure?: (response: Response) => any\n\n /**\n * The callback that is called when the request is complete. This callback will be called\n * after the request is complete and all data has been received.\n */\n onEnd?: (response: Response) => any\n}\n\n/**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\nexport async function request(route: string, options?: RequestOptions): Promise<unknown>\nexport async function request(route: string, options: RequestOptions = {}): Promise<unknown> {\n const response = await fetch(route, options)\n return await handleResponse(response, options)\n}\n"],"names":[],"mappings":";AAkEA,eAAsB,QAAQ,OAAe,UAA0B,IAAsB;AAC3F,QAAM,WAAW,MAAM,MAAM,OAAO,OAAO;AACpC,SAAA,MAAM,eAAe,UAAU,OAAO;AAC/C;"}
1
+ {"version":3,"file":"DJJsADWD.js","sources":["../../utils/request.ts"],"sourcesContent":["import type { ObjectLike } from '@unshared/types'\nimport type { FetchMethod, FetchOptions } from './parseRequest'\nimport { fetch } from './fetch'\nimport { handleResponse } from './handleResponse'\n\nexport interface RequestOptions<\n Method extends FetchMethod = FetchMethod,\n BaseUrl extends string = string,\n Parameters extends ObjectLike = ObjectLike,\n Query extends ObjectLike = ObjectLike,\n Body = unknown,\n Headers extends ObjectLike = ObjectLike,\n Data = any,\n Response = globalThis.Response,\n> extends\n FetchOptions<Method, BaseUrl, Parameters, Query, Body, Headers> {\n\n /**\n * The callback that is called when an error occurs during the request.\n */\n onError?: (error: Error) => any\n\n /**\n * The callback that is called when data is received from the request. This callback\n * will be called for each chunk of data that is received from the request.\n */\n onData?: (data: Data) => any\n\n /**\n * The callback that is called when the request is successful. This callback will be\n * called after the request is complete and all data has been received.\n */\n onSuccess?: (response: Response) => any\n\n /**\n * The callback that is called when the status code is not OK. This callback will be called\n * after the request is complete and before the data is consumed.\n */\n onFailure?: (response: Response) => any\n\n /**\n * The callback that is called when the request is complete. This callback will be called\n * after the request is complete and all data has been received.\n */\n onEnd?: (response: Response) => any\n}\n\n/**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\nexport async function request(route: string, options?: RequestOptions): Promise<unknown>\nexport async function request(route: string, options: RequestOptions = {}): Promise<unknown> {\n const response = await fetch(route, options)\n return await handleResponse(response, options)\n}\n"],"names":[],"mappings":";AAkEA,eAAsB,QAAQ,OAAe,UAA0B,IAAsB;AAC3F,QAAM,WAAW,MAAM,MAAM,OAAO,OAAO;AACpC,SAAA,MAAM,eAAe,UAAU,OAAO;AAC/C;"}
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
- var handleResponse = require("./CfKxYeRr.cjs");
2
+ var handleResponse = require("./Cayg8606.cjs");
3
3
  async function request(route, options = {}) {
4
4
  const response = await handleResponse.fetch(route, options);
5
5
  return await handleResponse.handleResponse(response, options);
6
6
  }
7
7
  exports.request = request;
8
- //# sourceMappingURL=iA98-4f5.cjs.map
8
+ //# sourceMappingURL=Du_W5H6e.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"iA98-4f5.cjs","sources":["../../utils/request.ts"],"sourcesContent":["import type { ObjectLike } from '@unshared/types'\nimport type { FetchMethod, FetchOptions } from './parseRequest'\nimport { fetch } from './fetch'\nimport { handleResponse } from './handleResponse'\n\nexport interface RequestOptions<\n Method extends FetchMethod = FetchMethod,\n BaseUrl extends string = string,\n Parameters extends ObjectLike = ObjectLike,\n Query extends ObjectLike = ObjectLike,\n Body = unknown,\n Headers extends ObjectLike = ObjectLike,\n Data = any,\n Response = globalThis.Response,\n> extends\n FetchOptions<Method, BaseUrl, Parameters, Query, Body, Headers> {\n\n /**\n * The callback that is called when an error occurs during the request.\n */\n onError?: (error: Error) => any\n\n /**\n * The callback that is called when data is received from the request. This callback\n * will be called for each chunk of data that is received from the request.\n */\n onData?: (data: Data) => any\n\n /**\n * The callback that is called when the request is successful. This callback will be\n * called after the request is complete and all data has been received.\n */\n onSuccess?: (response: Response) => any\n\n /**\n * The callback that is called when the status code is not OK. This callback will be called\n * after the request is complete and before the data is consumed.\n */\n onFailure?: (response: Response) => any\n\n /**\n * The callback that is called when the request is complete. This callback will be called\n * after the request is complete and all data has been received.\n */\n onEnd?: (response: Response) => any\n}\n\n/**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\nexport async function request(route: string, options?: RequestOptions): Promise<unknown>\nexport async function request(route: string, options: RequestOptions = {}): Promise<unknown> {\n const response = await fetch(route, options)\n return await handleResponse(response, options)\n}\n"],"names":["fetch","handleResponse"],"mappings":";;AAkEA,eAAsB,QAAQ,OAAe,UAA0B,IAAsB;AAC3F,QAAM,WAAW,MAAMA,qBAAM,OAAO,OAAO;AACpC,SAAA,MAAMC,eAAAA,eAAe,UAAU,OAAO;AAC/C;;"}
1
+ {"version":3,"file":"Du_W5H6e.cjs","sources":["../../utils/request.ts"],"sourcesContent":["import type { ObjectLike } from '@unshared/types'\nimport type { FetchMethod, FetchOptions } from './parseRequest'\nimport { fetch } from './fetch'\nimport { handleResponse } from './handleResponse'\n\nexport interface RequestOptions<\n Method extends FetchMethod = FetchMethod,\n BaseUrl extends string = string,\n Parameters extends ObjectLike = ObjectLike,\n Query extends ObjectLike = ObjectLike,\n Body = unknown,\n Headers extends ObjectLike = ObjectLike,\n Data = any,\n Response = globalThis.Response,\n> extends\n FetchOptions<Method, BaseUrl, Parameters, Query, Body, Headers> {\n\n /**\n * The callback that is called when an error occurs during the request.\n */\n onError?: (error: Error) => any\n\n /**\n * The callback that is called when data is received from the request. This callback\n * will be called for each chunk of data that is received from the request.\n */\n onData?: (data: Data) => any\n\n /**\n * The callback that is called when the request is successful. This callback will be\n * called after the request is complete and all data has been received.\n */\n onSuccess?: (response: Response) => any\n\n /**\n * The callback that is called when the status code is not OK. This callback will be called\n * after the request is complete and before the data is consumed.\n */\n onFailure?: (response: Response) => any\n\n /**\n * The callback that is called when the request is complete. This callback will be called\n * after the request is complete and all data has been received.\n */\n onEnd?: (response: Response) => any\n}\n\n/**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\nexport async function request(route: string, options?: RequestOptions): Promise<unknown>\nexport async function request(route: string, options: RequestOptions = {}): Promise<unknown> {\n const response = await fetch(route, options)\n return await handleResponse(response, options)\n}\n"],"names":["fetch","handleResponse"],"mappings":";;AAkEA,eAAsB,QAAQ,OAAe,UAA0B,IAAsB;AAC3F,QAAM,WAAW,MAAMA,qBAAM,OAAO,OAAO;AACpC,SAAA,MAAMC,eAAAA,eAAe,UAAU,OAAO;AAC/C;;"}
@@ -1,5 +1,5 @@
1
1
  import { Loose, UnionMerge, Override, Pretty, CollectKey, MaybeLiteral, StringSplit } from '@unshared/types';
2
- import { F as FetchMethod, c as RequestOptions } from './B92aAMq0.js';
2
+ import { F as FetchMethod, R as RequestOptions } from './CO11DuYE.js';
3
3
  import { OpenAPI } from 'openapi-types';
4
4
 
5
5
  /** Get the base URL of an OpenAPI specification. */
@@ -166,20 +166,20 @@ type OperationId<T> = T extends {
166
166
  operationId: infer N;
167
167
  } ? N : string : string : string : string;
168
168
  /** A union of possible Operations types in the specification. */
169
- type Operation = {
169
+ type Operation = OpenAPI.Operation & {
170
170
  method: FetchMethod;
171
171
  path: string;
172
- } & OpenAPI.Operation;
172
+ };
173
173
  /** Find an operation by its operationId in an OpenAPI specification. */
174
174
  type OperationById<T, U extends OperationId<T>> = T extends {
175
175
  paths: infer P;
176
176
  } ? CollectKey<P> extends Record<string, infer R> ? CollectKey<R> extends Record<string, infer O> ? O extends {
177
177
  $key: [infer P extends string, infer M extends string];
178
178
  operationId: U;
179
- } ? Pretty<{
179
+ } ? Pretty<Omit<O, '$key'> & {
180
180
  method: M;
181
181
  path: P;
182
- } & Omit<O, '$key'>> : never : never : never : never;
182
+ }> : never : never : never : never;
183
183
  /**
184
184
  * Given an OpenAPI specification, find an operation by its operationId.
185
185
  *
@@ -190,24 +190,19 @@ type OperationById<T, U extends OperationId<T>> = T extends {
190
190
  */
191
191
  declare function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U>;
192
192
 
193
- /** The options to pass to the request. */
194
- type OperationOptions<T, V extends Operation> = T extends {
193
+ interface OpenAPIV2Like {
195
194
  swagger: string;
196
- } ? RequestOptions<FetchMethod, MaybeLiteral<ServerUrl<T>>, OpenAPIV2.RequestParameters<V>, OpenAPIV2.RequestQuery<V>, OpenAPIV2.RequestBody<V>, OpenAPIV2.RequestHeaders<V>, OpenAPIV2.ResponseBody<V>, Response> : T extends {
195
+ }
196
+ interface OpenAPIV3Like {
197
197
  openapi: string;
198
- } ? RequestOptions<FetchMethod, MaybeLiteral<ServerUrl<T>>, OpenAPIV2.RequestParameters<V>, OpenAPIV3.RequestQuery<V> & OpenAPIV3.ServerQuery<T>, OpenAPIV3.RequestBody<V>, OpenAPIV2.RequestHeaders<V>, OpenAPIV3.ResponseBody<V>, Response> : RequestOptions;
198
+ }
199
+ type OpenAPILike = OpenAPIV2Like | OpenAPIV3Like;
200
+ /** The options to pass to the request. */
201
+ type OperationOptions<T, V extends Operation> = T extends OpenAPIV2Like ? RequestOptions<never, MaybeLiteral<ServerUrl<T>>, OpenAPIV2.RequestParameters<V>, OpenAPIV2.RequestQuery<V>, OpenAPIV2.RequestBody<V>, OpenAPIV2.RequestHeaders<V>, OpenAPIV2.ResponseBody<V>> : T extends OpenAPIV3Like ? RequestOptions<never, MaybeLiteral<ServerUrl<T>>, OpenAPIV2.RequestParameters<V>, OpenAPIV3.RequestQuery<V> & OpenAPIV3.ServerQuery<T>, OpenAPIV3.RequestBody<V>, OpenAPIV2.RequestHeaders<V>, OpenAPIV3.ResponseBody<V>> : RequestOptions;
199
202
  /** The response data from the operation. */
200
- type OperationResult<T, V extends Operation> = T extends {
201
- swagger: string;
202
- } ? OpenAPIV2.ResponseBody<V> : T extends {
203
- openapi: string;
204
- } ? OpenAPIV3.ResponseBody<V> : unknown;
203
+ type OperationResult<T, V extends Operation> = T extends OpenAPIV2Like ? OpenAPIV2.ResponseBody<V> : T extends OpenAPIV3Like ? OpenAPIV3.ResponseBody<V> : unknown;
205
204
  /** The `Response` object from the operation. */
206
- type OperationResponse<T, V extends Operation> = T extends {
207
- swagger: string;
208
- } ? OpenAPIV2.Response<V> : T extends {
209
- openapi: string;
210
- } ? OpenAPIV3.Response<V> : globalThis.Response;
205
+ type OperationResponse<T, V extends Operation> = T extends OpenAPIV2Like ? OpenAPIV2.Response<V> : T extends OpenAPIV3Like ? OpenAPIV3.Response<V> : globalThis.Response;
211
206
  /** Union of all operation route names in the specification. */
212
207
  type OperationRoute<T> = T extends {
213
208
  paths: infer P;
@@ -217,13 +212,13 @@ type OperationRoute<T> = T extends {
217
212
  /** Find an operation by its route name in an OpenAPI specification. */
218
213
  type OperationByRoute<T, U extends OperationRoute<T>> = StringSplit<U, ' '> extends [infer M extends string, infer P extends string] ? T extends {
219
214
  paths: infer U;
220
- } ? U extends Record<P, infer R> ? R extends Record<Lowercase<M>, infer O> ? Pretty<{
215
+ } ? U extends Record<P, infer R> ? R extends Record<Lowercase<M>, infer O> ? Pretty<O & {
221
216
  method: Lowercase<M>;
222
217
  path: P;
223
- } & O> : never : never : never : never;
218
+ }> : never : never : never : never;
224
219
  /** The `ClientRoutes` inferred from the OpenAPI specification. */
225
- type OpenAPIRoutes<T> = {
220
+ type OpenAPIOptionsMap<T> = {
226
221
  [K in OperationRoute<T>]: OperationOptions<T, OperationByRoute<T, K>>;
227
222
  };
228
223
 
229
- export { OpenAPIV2 as O, type ServerUrl as S, OpenAPIV3 as a, type OperationId as b, type Operation as c, type OperationById as d, type OperationOptions as e, type OperationResult as f, getServerUrl as g, type OperationResponse as h, type OperationRoute as i, type OperationByRoute as j, type OpenAPIRoutes as k, resolveOperation as r };
224
+ export { type OpenAPILike as O, type ServerUrl as S, type OpenAPIOptionsMap as a, type OperationId as b, type OperationById as c, type OperationOptions as d, type OperationResult as e, OpenAPIV3 as f, getServerUrl as g, OpenAPIV2 as h, type Operation as i, type OpenAPIV2Like as j, type OpenAPIV3Like as k, type OperationResponse as l, type OperationRoute as m, type OperationByRoute as n, resolveOperation as r };
@@ -1,15 +1,17 @@
1
1
  "use strict";
2
- var attempt = require("@unshared/functions/attempt"), handleResponse = require("./chunks/CfKxYeRr.cjs"), request = require("./chunks/iA98-4f5.cjs");
2
+ var attempt = require("@unshared/functions/attempt"), handleResponse = require("./chunks/Cayg8606.cjs"), request = require("./chunks/Du_W5H6e.cjs"), connect = require("./chunks/BMbsYNBd.cjs");
3
+ require("./chunks/CYmaYL5B.cjs");
3
4
  require("@unshared/functions/awaitable");
5
+ require("@unshared/functions");
4
6
  class Client {
5
7
  /**
6
8
  * Create a new client for the application.
7
9
  *
8
- * @param initialOptions The options to pass to the client.
10
+ * @param options The options to pass to the client.
9
11
  * @example new Client({ baseUrl: 'https://api.example.com' })
10
12
  */
11
- constructor(initialOptions = {}) {
12
- this.initialOptions = initialOptions;
13
+ constructor(options = {}) {
14
+ this.options = options;
13
15
  }
14
16
  /**
15
17
  * Fetch a route from the API and return the `Response` object. If the client was instantiated with an
@@ -20,8 +22,8 @@ class Client {
20
22
  * @param options The options to pass to the request.
21
23
  * @returns The response from the server.
22
24
  */
23
- async fetch(route, options) {
24
- return await handleResponse.fetch(route, { ...this.initialOptions, ...options });
25
+ fetch(route, options) {
26
+ return handleResponse.fetch(route, { ...this.options, ...options });
25
27
  }
26
28
  /**
27
29
  * Fetch a route from the API and return the data. If the client was instantiated with an
@@ -41,15 +43,15 @@ class Client {
41
43
  * // Fetch the data from the API.
42
44
  * const data = request('GET /api/product/:id', { data: { id: '1' } })
43
45
  */
44
- async request(route, options) {
45
- return await request.request(route, { ...this.initialOptions, ...options });
46
+ request(route, options) {
47
+ return request.request(route, { ...this.options, ...options });
46
48
  }
47
49
  /**
48
50
  * Attempt to fetch a route from the API and return the data. If the client was instantiated with an
49
51
  * application, the route name will be inferred from the application routes. Otherwise, you
50
52
  * can pass the route name as a string.
51
53
  *
52
- * @param name The name of the route to fetch.
54
+ * @param route The name of the route to fetch.
53
55
  * @param options The options to pass to the request.
54
56
  * @returns A result object with either the data or an error.
55
57
  * @example
@@ -64,20 +66,20 @@ class Client {
64
66
  * if (error) console.error(error)
65
67
  * else console.log(data)
66
68
  */
67
- async requestAttempt(name, options) {
68
- return await attempt.attempt(() => this.request(name, options));
69
+ requestAttempt(route, options) {
70
+ return attempt.attempt(() => this.request(route, options));
69
71
  }
70
72
  /**
71
73
  * Create a new WebSocket connection to the server with the given path. The connection will
72
74
  * automatically reconnect if the connection is closed unexpectedly.
73
75
  *
74
- * @param name The path to connect to.
76
+ * @param channel The path to connect to.
75
77
  * @param options The options to pass to the connection.
76
78
  * @returns The WebSocket connection.
77
79
  */
78
- // public connect<P extends RouteName<T>>(name: P, options: Partial<ConnectOptions<T, P>> = {}): WebSocketConnection<T, P> {
79
- // return connect<T, P>(name, { baseUrl: this.baseUrl, ...options })
80
- // }
80
+ connect(channel, options) {
81
+ return connect.connect(channel, { baseUrl: this.options.baseUrl, ...options });
82
+ }
81
83
  }
82
84
  function createClient(options) {
83
85
  return new Client(options);
@@ -1 +1 @@
1
- {"version":3,"file":"createClient.cjs","sources":["../createClient.ts"],"sourcesContent":["import type { Result } from '@unshared/functions/attempt'\nimport type { ObjectLike } from '@unshared/types'\nimport type { ServiceOptions } from './createService'\nimport type { OpenAPIRoutes } from './openapi'\nimport type { RequestOptions } from './utils/request'\nimport { attempt } from '@unshared/functions/attempt'\nimport { fetch } from './utils/fetch'\nimport { request } from './utils/request'\n\n/** Define the routes that can be fetched from the API and their related options. */\nexport type ClientRoutes = Record<string, RequestOptions>\n\n/** The route name that can be fetched from the API. */\ntype Route<T extends ClientRoutes> =\n T extends Record<infer P extends string, RequestOptions> ? P : string\n\n/** The options to pass to the request based on the route name. */\ntype Options<T extends ClientRoutes, P extends keyof T> =\n T extends Record<P, infer R> ? R : RequestOptions\n\n/** The data returned from the API based on the route name. */\ntype Data<T extends ClientRoutes, P extends keyof T> =\n Options<T, P> extends RequestOptions<any, any, any, any, any, any, infer R extends ObjectLike, any>\n ? R\n : unknown\n\nexport class Client<T extends ClientRoutes = ClientRoutes> {\n\n /**\n * Create a new client for the application.\n *\n * @param initialOptions The options to pass to the client.\n * @example new Client({ baseUrl: 'https://api.example.com' })\n */\n constructor(private initialOptions: RequestOptions = {}) {}\n\n /**\n * Fetch a route from the API and return the `Response` object. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The response from the server.\n */\n public async fetch<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Response> {\n return await fetch(route, { ...this.initialOptions, ...options })\n }\n\n /**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\n public async request<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Data<T, P>> {\n return await request(route, { ...this.initialOptions, ...options }) as Data<T, P>\n }\n\n /**\n * Attempt to fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param name The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns A result object with either the data or an error.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const { data, error } = requestAttempt('GET /api/product/:id', { data: { id: '1' } })\n * if (error) console.error(error)\n * else console.log(data)\n */\n public async requestAttempt<P extends Route<T>>(name: P, options?: Options<T, P>): Promise<Result<Data<T, P>>> {\n return await attempt(() => this.request<P>(name, options))\n }\n\n /**\n * Create a new WebSocket connection to the server with the given path. The connection will\n * automatically reconnect if the connection is closed unexpectedly.\n *\n * @param name The path to connect to.\n * @param options The options to pass to the connection.\n * @returns The WebSocket connection.\n */\n // public connect<P extends RouteName<T>>(name: P, options: Partial<ConnectOptions<T, P>> = {}): WebSocketConnection<T, P> {\n // return connect<T, P>(name, { baseUrl: this.baseUrl, ...options })\n // }\n}\n\n/**\n * Create a new type-safe client for the application. The client can be used to fetch data from\n * the API and connect to the server using WebSockets with the given path.\n *\n * @param options The options to pass to the client.\n * @returns The client object with the request method.\n * @example\n * // Create a type-safe client for the application.\n * const client = createClient<[ModuleUser]>()\n *\n * // Fetch the data from the API.\n * const data = await client.request('GET /api/user/:id', { id: '1' })\n *\n * // Use the data from the API.\n * console.log(data) // { id: '1', name: 'John Doe' }\n */\nexport function createClient<T extends ClientRoutes>(options?: RequestOptions): Client<T>\nexport function createClient<T extends { swagger: string }>(options?: ServiceOptions<T>): Client<OpenAPIRoutes<T>>\nexport function createClient<T extends { openapi: string }>(options?: ServiceOptions<T>): Client<OpenAPIRoutes<T>>\nexport function createClient(options?: RequestOptions): Client {\n return new Client(options)\n}\n"],"names":["fetch","request","attempt"],"mappings":";;;AA0BO,MAAM,OAA8C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzD,YAAoB,iBAAiC,IAAI;AAArC,SAAA,iBAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWpB,MAAa,MAA0B,OAAU,SAA4C;AACpF,WAAA,MAAMA,qBAAM,OAAO,EAAE,GAAG,KAAK,gBAAgB,GAAG,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBlE,MAAa,QAA4B,OAAU,SAA8C;AACxF,WAAA,MAAMC,gBAAQ,OAAO,EAAE,GAAG,KAAK,gBAAgB,GAAG,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBpE,MAAa,eAAmC,MAAS,SAAsD;AAC7G,WAAO,MAAMC,QAAQ,QAAA,MAAM,KAAK,QAAW,MAAM,OAAO,CAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc7D;AAqBO,SAAS,aAAa,SAAkC;AACtD,SAAA,IAAI,OAAO,OAAO;AAC3B;;;"}
1
+ {"version":3,"file":"createClient.cjs","sources":["../createClient.ts"],"sourcesContent":["import type { Awaitable } from '@unshared/functions'\nimport type { Result } from '@unshared/functions/attempt'\nimport type { ServiceOptions } from './createService'\nimport type { OpenAPILike, OpenAPIOptionsMap } from './openapi'\nimport type { RequestOptions } from './utils'\nimport type { ConnectOptions, WebSocketChannel } from './websocket'\nimport { attempt } from '@unshared/functions/attempt'\nimport { fetch } from './utils/fetch'\nimport { request } from './utils/request'\nimport { connect } from './websocket/connect'\n\ntype Data<T extends RequestOptions> = T extends RequestOptions<any, any, any, any, any, any, infer R, any> ? R : unknown\ntype Routes = Record<string, RequestOptions>\ntype Channels = Record<string, ConnectOptions>\n\nexport class Client<T extends Routes = Routes, U extends Channels = Channels> {\n\n /**\n * Create a new client for the application.\n *\n * @param options The options to pass to the client.\n * @example new Client({ baseUrl: 'https://api.example.com' })\n */\n constructor(public options: RequestOptions = {}) {}\n\n /**\n * Fetch a route from the API and return the `Response` object. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The response from the server.\n */\n public fetch<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Response> {\n return fetch(route, { ...this.options, ...options })\n }\n\n /**\n * Fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns The data from the API.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const data = request('GET /api/product/:id', { data: { id: '1' } })\n */\n public request<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Data<V>> {\n return request(route, { ...this.options, ...options }) as Promise<Data<V>>\n }\n\n /**\n * Attempt to fetch a route from the API and return the data. If the client was instantiated with an\n * application, the route name will be inferred from the application routes. Otherwise, you\n * can pass the route name as a string.\n *\n * @param route The name of the route to fetch.\n * @param options The options to pass to the request.\n * @returns A result object with either the data or an error.\n * @example\n * // Declare the application type.\n * type App = Application<[ModuleProduct]>\n *\n * // Create a type-safe client for the application.\n * const request = createClient<App>()\n *\n * // Fetch the data from the API.\n * const { data, error } = requestAttempt('GET /api/product/:id', { data: { id: '1' } })\n * if (error) console.error(error)\n * else console.log(data)\n */\n public requestAttempt<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Result<Data<V>>> {\n return attempt(() => this.request(route, options))\n }\n\n /**\n * Create a new WebSocket connection to the server with the given path. The connection will\n * automatically reconnect if the connection is closed unexpectedly.\n *\n * @param channel The path to connect to.\n * @param options The options to pass to the connection.\n * @returns The WebSocket connection.\n */\n public connect<P extends keyof U & string, V extends U[P]>(channel: P, options?: V): Awaitable<WebSocketChannel<V>, WebSocketChannel<V>> {\n return connect(channel, { baseUrl: this.options.baseUrl, ...options }) as Awaitable<WebSocketChannel<V>, WebSocketChannel<V>>\n }\n}\n\n/**\n * Create a new type-safe client for the application. The client can be used to fetch data from\n * the API and connect to the server using WebSockets with the given path.\n *\n * @param options The options to pass to the client.\n * @returns The client object with the request method.\n * @example\n * // Create a type-safe client for the application.\n * const client = createClient<[ModuleUser]>()\n *\n * // Fetch the data from the API.\n * const data = await client.request('GET /api/user/:id', { id: '1' })\n *\n * // Use the data from the API.\n * console.log(data) // { id: '1', name: 'John Doe' }\n */\nexport function createClient<T extends OpenAPILike>(options?: ServiceOptions<T>): Client<OpenAPIOptionsMap<T>>\n\n/**\n * Create a new type-safe client for the application. The client can be used to fetch data from\n * the API and connect to the server using WebSockets with the given path.\n *\n * @param options The options to pass to the client.\n * @returns The client object with the request method.\n * @example\n * // Create a type-safe client for the application.\n * const client = createClient<[ModuleUser]>()\n *\n * // Fetch the data from the API.\n * const data = await client.request('GET /api/user/:id', { id: '1' })\n *\n * // Use the data from the API.\n * console.log(data) // { id: '1', name: 'John Doe' }\n */\nexport function createClient<T extends Routes = Routes, V extends Channels = Channels>(options?: RequestOptions): Client<T, V>\nexport function createClient(options?: RequestOptions): Client {\n return new Client(options)\n}\n"],"names":["fetch","request","attempt","connect"],"mappings":";;;;;AAeO,MAAM,OAAiE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5E,YAAmB,UAA0B,IAAI;AAA9B,SAAA,UAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWZ,MAAkD,OAAU,SAAgC;AAC1F,WAAAA,eAAAA,MAAM,OAAO,EAAE,GAAG,KAAK,SAAS,GAAG,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqB9C,QAAoD,OAAU,SAA+B;AAC3F,WAAAC,QAAAA,QAAQ,OAAO,EAAE,GAAG,KAAK,SAAS,GAAG,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBhD,eAA2D,OAAU,SAAuC;AACjH,WAAOC,QAAAA,QAAQ,MAAM,KAAK,QAAQ,OAAO,OAAO,CAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW5C,QAAoD,SAAY,SAAkE;AAChI,WAAAC,QAAA,QAAQ,SAAS,EAAE,SAAS,KAAK,QAAQ,SAAS,GAAG,SAAS;AAAA,EAAA;AAEzE;AAqCO,SAAS,aAAa,SAAkC;AACtD,SAAA,IAAI,OAAO,OAAO;AAC3B;;;"}
@@ -1,29 +1,26 @@
1
+ import { Awaitable } from '@unshared/functions';
1
2
  import { Result } from '@unshared/functions/attempt';
2
- import { ObjectLike } from '@unshared/types';
3
3
  import { ServiceOptions } from './createService.js';
4
- import { k as OpenAPIRoutes } from './chunks/CjU0376e.js';
5
- import { c as RequestOptions } from './chunks/B92aAMq0.js';
4
+ import { O as OpenAPILike, a as OpenAPIOptionsMap } from './chunks/mHfUAX_g.js';
5
+ import { R as RequestOptions } from './chunks/CO11DuYE.js';
6
+ import { WebSocketChannel, ConnectOptions } from './websocket.js';
7
+ import '@unshared/types';
6
8
  import 'openapi-types';
7
9
  import './HttpHeaders.js';
8
10
  import './HttpMethods.js';
9
11
 
10
- /** Define the routes that can be fetched from the API and their related options. */
11
- type ClientRoutes = Record<string, RequestOptions>;
12
- /** The route name that can be fetched from the API. */
13
- type Route<T extends ClientRoutes> = T extends Record<infer P extends string, RequestOptions> ? P : string;
14
- /** The options to pass to the request based on the route name. */
15
- type Options<T extends ClientRoutes, P extends keyof T> = T extends Record<P, infer R> ? R : RequestOptions;
16
- /** The data returned from the API based on the route name. */
17
- type Data<T extends ClientRoutes, P extends keyof T> = Options<T, P> extends RequestOptions<any, any, any, any, any, any, infer R extends ObjectLike, any> ? R : unknown;
18
- declare class Client<T extends ClientRoutes = ClientRoutes> {
19
- private initialOptions;
12
+ type Data<T extends RequestOptions> = T extends RequestOptions<any, any, any, any, any, any, infer R, any> ? R : unknown;
13
+ type Routes = Record<string, RequestOptions>;
14
+ type Channels = Record<string, ConnectOptions>;
15
+ declare class Client<T extends Routes = Routes, U extends Channels = Channels> {
16
+ options: RequestOptions;
20
17
  /**
21
18
  * Create a new client for the application.
22
19
  *
23
- * @param initialOptions The options to pass to the client.
20
+ * @param options The options to pass to the client.
24
21
  * @example new Client({ baseUrl: 'https://api.example.com' })
25
22
  */
26
- constructor(initialOptions?: RequestOptions);
23
+ constructor(options?: RequestOptions);
27
24
  /**
28
25
  * Fetch a route from the API and return the `Response` object. If the client was instantiated with an
29
26
  * application, the route name will be inferred from the application routes. Otherwise, you
@@ -33,7 +30,7 @@ declare class Client<T extends ClientRoutes = ClientRoutes> {
33
30
  * @param options The options to pass to the request.
34
31
  * @returns The response from the server.
35
32
  */
36
- fetch<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Response>;
33
+ fetch<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Response>;
37
34
  /**
38
35
  * Fetch a route from the API and return the data. If the client was instantiated with an
39
36
  * application, the route name will be inferred from the application routes. Otherwise, you
@@ -52,13 +49,13 @@ declare class Client<T extends ClientRoutes = ClientRoutes> {
52
49
  * // Fetch the data from the API.
53
50
  * const data = request('GET /api/product/:id', { data: { id: '1' } })
54
51
  */
55
- request<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Data<T, P>>;
52
+ request<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Data<V>>;
56
53
  /**
57
54
  * Attempt to fetch a route from the API and return the data. If the client was instantiated with an
58
55
  * application, the route name will be inferred from the application routes. Otherwise, you
59
56
  * can pass the route name as a string.
60
57
  *
61
- * @param name The name of the route to fetch.
58
+ * @param route The name of the route to fetch.
62
59
  * @param options The options to pass to the request.
63
60
  * @returns A result object with either the data or an error.
64
61
  * @example
@@ -73,7 +70,16 @@ declare class Client<T extends ClientRoutes = ClientRoutes> {
73
70
  * if (error) console.error(error)
74
71
  * else console.log(data)
75
72
  */
76
- requestAttempt<P extends Route<T>>(name: P, options?: Options<T, P>): Promise<Result<Data<T, P>>>;
73
+ requestAttempt<K extends keyof T & string, V extends T[K]>(route: K, options?: V): Promise<Result<Data<V>>>;
74
+ /**
75
+ * Create a new WebSocket connection to the server with the given path. The connection will
76
+ * automatically reconnect if the connection is closed unexpectedly.
77
+ *
78
+ * @param channel The path to connect to.
79
+ * @param options The options to pass to the connection.
80
+ * @returns The WebSocket connection.
81
+ */
82
+ connect<P extends keyof U & string, V extends U[P]>(channel: P, options?: V): Awaitable<WebSocketChannel<V>, WebSocketChannel<V>>;
77
83
  }
78
84
  /**
79
85
  * Create a new type-safe client for the application. The client can be used to fetch data from
@@ -91,12 +97,23 @@ declare class Client<T extends ClientRoutes = ClientRoutes> {
91
97
  * // Use the data from the API.
92
98
  * console.log(data) // { id: '1', name: 'John Doe' }
93
99
  */
94
- declare function createClient<T extends ClientRoutes>(options?: RequestOptions): Client<T>;
95
- declare function createClient<T extends {
96
- swagger: string;
97
- }>(options?: ServiceOptions<T>): Client<OpenAPIRoutes<T>>;
98
- declare function createClient<T extends {
99
- openapi: string;
100
- }>(options?: ServiceOptions<T>): Client<OpenAPIRoutes<T>>;
100
+ declare function createClient<T extends OpenAPILike>(options?: ServiceOptions<T>): Client<OpenAPIOptionsMap<T>>;
101
+ /**
102
+ * Create a new type-safe client for the application. The client can be used to fetch data from
103
+ * the API and connect to the server using WebSockets with the given path.
104
+ *
105
+ * @param options The options to pass to the client.
106
+ * @returns The client object with the request method.
107
+ * @example
108
+ * // Create a type-safe client for the application.
109
+ * const client = createClient<[ModuleUser]>()
110
+ *
111
+ * // Fetch the data from the API.
112
+ * const data = await client.request('GET /api/user/:id', { id: '1' })
113
+ *
114
+ * // Use the data from the API.
115
+ * console.log(data) // { id: '1', name: 'John Doe' }
116
+ */
117
+ declare function createClient<T extends Routes = Routes, V extends Channels = Channels>(options?: RequestOptions): Client<T, V>;
101
118
 
102
- export { Client, type ClientRoutes, createClient };
119
+ export { Client, createClient };