@unshared/client 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HttpHeaders.cjs +4 -0
- package/dist/HttpHeaders.cjs.map +1 -0
- package/dist/{chunks/8BFCFxqa.d.ts → HttpHeaders.d.ts} +1 -1
- package/dist/HttpHeaders.js +5 -0
- package/dist/HttpHeaders.js.map +1 -0
- package/dist/HttpMethods.cjs +4 -0
- package/dist/HttpMethods.cjs.map +1 -0
- package/dist/{chunks/DZp6zyqV.d.ts → HttpMethods.d.ts} +1 -98
- package/dist/HttpMethods.js +5 -0
- package/dist/HttpMethods.js.map +1 -0
- package/dist/HttpStatusCodes.cjs +4 -0
- package/dist/HttpStatusCodes.cjs.map +1 -0
- package/dist/HttpStatusCodes.d.ts +615 -0
- package/dist/HttpStatusCodes.js +5 -0
- package/dist/HttpStatusCodes.js.map +1 -0
- package/dist/chunks/B92aAMq0.d.ts +144 -0
- package/dist/chunks/{D-WqCFul.js → Biic1J5b.js} +11 -9
- package/dist/chunks/Biic1J5b.js.map +1 -0
- package/dist/chunks/CfKxYeRr.cjs +155 -0
- package/dist/chunks/CfKxYeRr.cjs.map +1 -0
- package/dist/chunks/CjU0376e.d.ts +229 -0
- package/dist/chunks/{xRZPkxch.cjs → CtW2aMuA.cjs} +11 -9
- package/dist/chunks/CtW2aMuA.cjs.map +1 -0
- package/dist/chunks/D51s1VII.js +156 -0
- package/dist/chunks/D51s1VII.js.map +1 -0
- package/dist/chunks/iA98-4f5.cjs +8 -0
- package/dist/chunks/iA98-4f5.cjs.map +1 -0
- package/dist/chunks/lMH6B5BV.js +9 -0
- package/dist/chunks/lMH6B5BV.js.map +1 -0
- package/dist/createClient.cjs +81 -18
- package/dist/createClient.cjs.map +1 -1
- package/dist/createClient.d.ts +93 -29
- package/dist/createClient.js +83 -20
- package/dist/createClient.js.map +1 -1
- package/dist/createService.cjs +17 -0
- package/dist/createService.cjs.map +1 -0
- package/dist/createService.d.ts +38 -0
- package/dist/createService.js +19 -0
- package/dist/createService.js.map +1 -0
- package/dist/index.cjs +22 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -624
- package/dist/index.js +24 -19
- package/dist/index.js.map +1 -1
- package/dist/openapi.cjs +3 -15
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.ts +7 -35
- package/dist/openapi.js +3 -15
- package/dist/openapi.js.map +1 -1
- package/dist/utils.cjs +13 -11
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +57 -27
- package/dist/utils.js +11 -9
- package/package.json +23 -8
- package/dist/chunks/B2OrSen1.d.ts +0 -185
- package/dist/chunks/B5hc73Po.js +0 -96
- package/dist/chunks/B5hc73Po.js.map +0 -1
- package/dist/chunks/CKfJvIQ8.js +0 -50
- package/dist/chunks/CKfJvIQ8.js.map +0 -1
- package/dist/chunks/Cx8m1YzL.cjs +0 -49
- package/dist/chunks/Cx8m1YzL.cjs.map +0 -1
- package/dist/chunks/D-WqCFul.js.map +0 -1
- package/dist/chunks/D8Tsm7xC.cjs +0 -95
- package/dist/chunks/D8Tsm7xC.cjs.map +0 -1
- package/dist/chunks/r8pYO6Hx.d.ts +0 -38
- package/dist/chunks/xRZPkxch.cjs.map +0 -1
- package/dist/fetch.cjs +0 -8
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.ts +0 -16
- package/dist/fetch.js +0 -9
- package/dist/fetch.js.map +0 -1
package/dist/createClient.cjs
CHANGED
@@ -1,24 +1,87 @@
|
|
1
1
|
"use strict";
|
2
|
-
var
|
3
|
-
require("./chunks/D8Tsm7xC.cjs");
|
2
|
+
var attempt = require("@unshared/functions/attempt"), handleResponse = require("./chunks/CfKxYeRr.cjs"), request = require("./chunks/iA98-4f5.cjs");
|
4
3
|
require("@unshared/functions/awaitable");
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
const status = response.status.toString();
|
15
|
-
throw status in responses && typeof responses[status] == "object" && responses[status] !== null && "description" in responses[status] && typeof responses[status].description == "string" ? new Error(responses[status].description) : new Error(response.statusText);
|
4
|
+
class Client {
|
5
|
+
/**
|
6
|
+
* Create a new client for the application.
|
7
|
+
*
|
8
|
+
* @param initialOptions The options to pass to the client.
|
9
|
+
* @example new Client({ baseUrl: 'https://api.example.com' })
|
10
|
+
*/
|
11
|
+
constructor(initialOptions = {}) {
|
12
|
+
this.initialOptions = initialOptions;
|
16
13
|
}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
/**
|
15
|
+
* Fetch a route from the API and return the `Response` object. If the client was instantiated with an
|
16
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
17
|
+
* can pass the route name as a string.
|
18
|
+
*
|
19
|
+
* @param route The name of the route to fetch.
|
20
|
+
* @param options The options to pass to the request.
|
21
|
+
* @returns The response from the server.
|
22
|
+
*/
|
23
|
+
async fetch(route, options) {
|
24
|
+
return await handleResponse.fetch(route, { ...this.initialOptions, ...options });
|
25
|
+
}
|
26
|
+
/**
|
27
|
+
* Fetch a route from the API and return the data. If the client was instantiated with an
|
28
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
29
|
+
* can pass the route name as a string.
|
30
|
+
*
|
31
|
+
* @param route The name of the route to fetch.
|
32
|
+
* @param options The options to pass to the request.
|
33
|
+
* @returns The data from the API.
|
34
|
+
* @example
|
35
|
+
* // Declare the application type.
|
36
|
+
* type App = Application<[ModuleProduct]>
|
37
|
+
*
|
38
|
+
* // Create a type-safe client for the application.
|
39
|
+
* const request = createClient<App>()
|
40
|
+
*
|
41
|
+
* // Fetch the data from the API.
|
42
|
+
* const data = request('GET /api/product/:id', { data: { id: '1' } })
|
43
|
+
*/
|
44
|
+
async request(route, options) {
|
45
|
+
return await request.request(route, { ...this.initialOptions, ...options });
|
46
|
+
}
|
47
|
+
/**
|
48
|
+
* Attempt to fetch a route from the API and return the data. If the client was instantiated with an
|
49
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
50
|
+
* can pass the route name as a string.
|
51
|
+
*
|
52
|
+
* @param name The name of the route to fetch.
|
53
|
+
* @param options The options to pass to the request.
|
54
|
+
* @returns A result object with either the data or an error.
|
55
|
+
* @example
|
56
|
+
* // Declare the application type.
|
57
|
+
* type App = Application<[ModuleProduct]>
|
58
|
+
*
|
59
|
+
* // Create a type-safe client for the application.
|
60
|
+
* const request = createClient<App>()
|
61
|
+
*
|
62
|
+
* // Fetch the data from the API.
|
63
|
+
* const { data, error } = requestAttempt('GET /api/product/:id', { data: { id: '1' } })
|
64
|
+
* if (error) console.error(error)
|
65
|
+
* else console.log(data)
|
66
|
+
*/
|
67
|
+
async requestAttempt(name, options) {
|
68
|
+
return await attempt.attempt(() => this.request(name, options));
|
69
|
+
}
|
70
|
+
/**
|
71
|
+
* Create a new WebSocket connection to the server with the given path. The connection will
|
72
|
+
* automatically reconnect if the connection is closed unexpectedly.
|
73
|
+
*
|
74
|
+
* @param name The path to connect to.
|
75
|
+
* @param options The options to pass to the connection.
|
76
|
+
* @returns The WebSocket connection.
|
77
|
+
*/
|
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
|
+
// }
|
81
|
+
}
|
82
|
+
function createClient(options) {
|
83
|
+
return new Client(options);
|
22
84
|
}
|
85
|
+
exports.Client = Client;
|
23
86
|
exports.createClient = createClient;
|
24
87
|
//# sourceMappingURL=createClient.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"createClient.cjs","sources":["../createClient.ts"],"sourcesContent":["import type {
|
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;;;"}
|
package/dist/createClient.d.ts
CHANGED
@@ -1,38 +1,102 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import { c as RequestOptions } from './chunks/
|
6
|
-
import '
|
1
|
+
import { Result } from '@unshared/functions/attempt';
|
2
|
+
import { ObjectLike } from '@unshared/types';
|
3
|
+
import { ServiceOptions } from './createService.js';
|
4
|
+
import { k as OpenAPIRoutes } from './chunks/CjU0376e.js';
|
5
|
+
import { c as RequestOptions } from './chunks/B92aAMq0.js';
|
6
|
+
import 'openapi-types';
|
7
|
+
import './HttpHeaders.js';
|
8
|
+
import './HttpMethods.js';
|
7
9
|
|
8
|
-
|
9
|
-
type
|
10
|
-
|
11
|
-
type
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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;
|
18
20
|
/**
|
19
|
-
*
|
21
|
+
* Create a new client for the application.
|
20
22
|
*
|
21
|
-
* @
|
23
|
+
* @param initialOptions The options to pass to the client.
|
24
|
+
* @example new Client({ baseUrl: 'https://api.example.com' })
|
22
25
|
*/
|
23
|
-
|
24
|
-
|
26
|
+
constructor(initialOptions?: RequestOptions);
|
27
|
+
/**
|
28
|
+
* Fetch a route from the API and return the `Response` object. If the client was instantiated with an
|
29
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
30
|
+
* can pass the route name as a string.
|
31
|
+
*
|
32
|
+
* @param route The name of the route to fetch.
|
33
|
+
* @param options The options to pass to the request.
|
34
|
+
* @returns The response from the server.
|
35
|
+
*/
|
36
|
+
fetch<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Response>;
|
37
|
+
/**
|
38
|
+
* Fetch a route from the API and return the data. If the client was instantiated with an
|
39
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
40
|
+
* can pass the route name as a string.
|
41
|
+
*
|
42
|
+
* @param route The name of the route to fetch.
|
43
|
+
* @param options The options to pass to the request.
|
44
|
+
* @returns The data from the API.
|
45
|
+
* @example
|
46
|
+
* // Declare the application type.
|
47
|
+
* type App = Application<[ModuleProduct]>
|
48
|
+
*
|
49
|
+
* // Create a type-safe client for the application.
|
50
|
+
* const request = createClient<App>()
|
51
|
+
*
|
52
|
+
* // Fetch the data from the API.
|
53
|
+
* const data = request('GET /api/product/:id', { data: { id: '1' } })
|
54
|
+
*/
|
55
|
+
request<P extends Route<T>>(route: P, options?: Options<T, P>): Promise<Data<T, P>>;
|
56
|
+
/**
|
57
|
+
* Attempt to fetch a route from the API and return the data. If the client was instantiated with an
|
58
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
59
|
+
* can pass the route name as a string.
|
60
|
+
*
|
61
|
+
* @param name The name of the route to fetch.
|
62
|
+
* @param options The options to pass to the request.
|
63
|
+
* @returns A result object with either the data or an error.
|
64
|
+
* @example
|
65
|
+
* // Declare the application type.
|
66
|
+
* type App = Application<[ModuleProduct]>
|
67
|
+
*
|
68
|
+
* // Create a type-safe client for the application.
|
69
|
+
* const request = createClient<App>()
|
70
|
+
*
|
71
|
+
* // Fetch the data from the API.
|
72
|
+
* const { data, error } = requestAttempt('GET /api/product/:id', { data: { id: '1' } })
|
73
|
+
* if (error) console.error(error)
|
74
|
+
* else console.log(data)
|
75
|
+
*/
|
76
|
+
requestAttempt<P extends Route<T>>(name: P, options?: Options<T, P>): Promise<Result<Data<T, P>>>;
|
77
|
+
}
|
25
78
|
/**
|
26
|
-
* Create a new client
|
79
|
+
* Create a new type-safe client for the application. The client can be used to fetch data from
|
80
|
+
* the API and connect to the server using WebSockets with the given path.
|
27
81
|
*
|
28
|
-
* @param
|
29
|
-
* @
|
30
|
-
* @returns The client instance.
|
82
|
+
* @param options The options to pass to the client.
|
83
|
+
* @returns The client object with the request method.
|
31
84
|
* @example
|
32
|
-
*
|
33
|
-
*
|
85
|
+
* // Create a type-safe client for the application.
|
86
|
+
* const client = createClient<[ModuleUser]>()
|
87
|
+
*
|
88
|
+
* // Fetch the data from the API.
|
89
|
+
* const data = await client.request('GET /api/user/:id', { id: '1' })
|
90
|
+
*
|
91
|
+
* // Use the data from the API.
|
92
|
+
* console.log(data) // { id: '1', name: 'John Doe' }
|
34
93
|
*/
|
35
|
-
declare function createClient<T extends
|
36
|
-
declare function createClient<T extends
|
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>>;
|
37
101
|
|
38
|
-
export {
|
102
|
+
export { Client, type ClientRoutes, createClient };
|
package/dist/createClient.js
CHANGED
@@ -1,27 +1,90 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import "./chunks/B5hc73Po.js";
|
1
|
+
import { attempt } from "@unshared/functions/attempt";
|
2
|
+
import { f as fetch } from "./chunks/D51s1VII.js";
|
3
|
+
import { r as request } from "./chunks/lMH6B5BV.js";
|
5
4
|
import "@unshared/functions/awaitable";
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
const status = response.status.toString();
|
16
|
-
throw status in responses && typeof responses[status] == "object" && responses[status] !== null && "description" in responses[status] && typeof responses[status].description == "string" ? new Error(responses[status].description) : new Error(response.statusText);
|
5
|
+
class Client {
|
6
|
+
/**
|
7
|
+
* Create a new client for the application.
|
8
|
+
*
|
9
|
+
* @param initialOptions The options to pass to the client.
|
10
|
+
* @example new Client({ baseUrl: 'https://api.example.com' })
|
11
|
+
*/
|
12
|
+
constructor(initialOptions = {}) {
|
13
|
+
this.initialOptions = initialOptions;
|
17
14
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
/**
|
16
|
+
* Fetch a route from the API and return the `Response` object. If the client was instantiated with an
|
17
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
18
|
+
* can pass the route name as a string.
|
19
|
+
*
|
20
|
+
* @param route The name of the route to fetch.
|
21
|
+
* @param options The options to pass to the request.
|
22
|
+
* @returns The response from the server.
|
23
|
+
*/
|
24
|
+
async fetch(route, options) {
|
25
|
+
return await fetch(route, { ...this.initialOptions, ...options });
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* Fetch a route from the API and return the data. If the client was instantiated with an
|
29
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
30
|
+
* can pass the route name as a string.
|
31
|
+
*
|
32
|
+
* @param route The name of the route to fetch.
|
33
|
+
* @param options The options to pass to the request.
|
34
|
+
* @returns The data from the API.
|
35
|
+
* @example
|
36
|
+
* // Declare the application type.
|
37
|
+
* type App = Application<[ModuleProduct]>
|
38
|
+
*
|
39
|
+
* // Create a type-safe client for the application.
|
40
|
+
* const request = createClient<App>()
|
41
|
+
*
|
42
|
+
* // Fetch the data from the API.
|
43
|
+
* const data = request('GET /api/product/:id', { data: { id: '1' } })
|
44
|
+
*/
|
45
|
+
async request(route, options) {
|
46
|
+
return await request(route, { ...this.initialOptions, ...options });
|
47
|
+
}
|
48
|
+
/**
|
49
|
+
* Attempt to fetch a route from the API and return the data. If the client was instantiated with an
|
50
|
+
* application, the route name will be inferred from the application routes. Otherwise, you
|
51
|
+
* can pass the route name as a string.
|
52
|
+
*
|
53
|
+
* @param name The name of the route to fetch.
|
54
|
+
* @param options The options to pass to the request.
|
55
|
+
* @returns A result object with either the data or an error.
|
56
|
+
* @example
|
57
|
+
* // Declare the application type.
|
58
|
+
* type App = Application<[ModuleProduct]>
|
59
|
+
*
|
60
|
+
* // Create a type-safe client for the application.
|
61
|
+
* const request = createClient<App>()
|
62
|
+
*
|
63
|
+
* // Fetch the data from the API.
|
64
|
+
* const { data, error } = requestAttempt('GET /api/product/:id', { data: { id: '1' } })
|
65
|
+
* if (error) console.error(error)
|
66
|
+
* else console.log(data)
|
67
|
+
*/
|
68
|
+
async requestAttempt(name, options) {
|
69
|
+
return await attempt(() => this.request(name, options));
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* Create a new WebSocket connection to the server with the given path. The connection will
|
73
|
+
* automatically reconnect if the connection is closed unexpectedly.
|
74
|
+
*
|
75
|
+
* @param name The path to connect to.
|
76
|
+
* @param options The options to pass to the connection.
|
77
|
+
* @returns The WebSocket connection.
|
78
|
+
*/
|
79
|
+
// public connect<P extends RouteName<T>>(name: P, options: Partial<ConnectOptions<T, P>> = {}): WebSocketConnection<T, P> {
|
80
|
+
// return connect<T, P>(name, { baseUrl: this.baseUrl, ...options })
|
81
|
+
// }
|
82
|
+
}
|
83
|
+
function createClient(options) {
|
84
|
+
return new Client(options);
|
23
85
|
}
|
24
86
|
export {
|
87
|
+
Client,
|
25
88
|
createClient
|
26
89
|
};
|
27
90
|
//# sourceMappingURL=createClient.js.map
|
package/dist/createClient.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"createClient.js","sources":["../createClient.ts"],"sourcesContent":["import type {
|
1
|
+
{"version":3,"file":"createClient.js","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":[],"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,MAAM,MAAM,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,MAAM,QAAQ,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,MAAM,QAAQ,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;"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
var resolveOperation = require("./chunks/CtW2aMuA.cjs"), handleResponse = require("./chunks/CfKxYeRr.cjs");
|
3
|
+
require("@unshared/functions/awaitable");
|
4
|
+
function createService(document, initialOptions) {
|
5
|
+
return new Proxy({}, {
|
6
|
+
get(_, id) {
|
7
|
+
return async (data, options) => {
|
8
|
+
const baseUrl = resolveOperation.getServerUrl(document), operation = resolveOperation.resolveOperation(document, id), { method, path, responses = {} } = operation, response = await handleResponse.fetch(path, { method, baseUrl, data, ...initialOptions, ...options });
|
9
|
+
if (response.ok) return handleResponse.handleResponse(response, { ...initialOptions, ...options });
|
10
|
+
const status = response.status.toString();
|
11
|
+
throw status in responses && typeof responses[status] == "object" && responses[status] !== null && "description" in responses[status] && typeof responses[status].description == "string" ? new Error(responses[status].description) : new Error(response.statusText);
|
12
|
+
};
|
13
|
+
}
|
14
|
+
});
|
15
|
+
}
|
16
|
+
exports.createService = createService;
|
17
|
+
//# sourceMappingURL=createService.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createService.cjs","sources":["../createService.ts"],"sourcesContent":["import type { MaybeLiteral } from '@unshared/types'\nimport type { OpenAPIV3, Operation, OperationById, OperationId, OperationOptions, OperationResult, ServerUrl } from './openapi'\nimport type { RequestOptions } from './utils/request'\nimport { getServerUrl } from './openapi/getServerUrl'\nimport { resolveOperation } from './openapi/resolveOperation'\nimport { fetch } from './utils/fetch'\nimport { handleResponse } from './utils/handleResponse'\n\n/** A service instance for the given OpenAPI specification. */\nexport type Service<T> = {\n [K in OperationId<T>]:\n OperationById<T, K> extends infer U extends OperationById<T, K>\n ? (data: OperationOptions<T, U>['data'], options?: OperationOptions<T, U>) => Promise<OperationResult<T, U>>\n : never\n}\n\n/** The options to pass to the service client. */\nexport interface ServiceOptions<T = any> extends RequestOptions {\n baseUrl?: MaybeLiteral<ServerUrl<T>>\n headers?: T extends { openapi: string } ? OpenAPIV3.ServerHeaders<T> : never\n}\n\n/**\n * Create a new client instance for the given OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param initialOptions The initial options to use for every request.\n * @returns The client instance.\n * @example\n *\n * // Import the Giphy OpenAPI specification.\n * import Giphy from './giphy.openapi.json'\n *\n * // Create a new service instance for the Giphy API.\n * const service = createService(Giphy, { headers: { 'Bearer' } })\n *\n * // Request the \"searchGifs\" operation from the Giphy API.\n * await service.getGifs({ limit: 10, offset: 0, q: 'cats' }) // => { data: [...] }\n */\nexport function createService<T extends object>(document: Readonly<T>, initialOptions?: ServiceOptions<T>): Service<T> {\n return new Proxy({}, {\n get(_, id: OperationId<T>) {\n return async(data: object, options: RequestOptions) => {\n\n // --- Find the operation in the OpenAPI specification.\n const baseUrl = getServerUrl(document)\n const operation = resolveOperation(document, id) as Operation\n\n // --- Fetch the relevant resource from the server.\n const { method, path, responses = {} } = operation\n const response = await fetch(path, { method, baseUrl, data, ...initialOptions, ...options })\n if (response.ok) return handleResponse(response, { ...initialOptions, ...options })\n\n // --- Throw an error if the response was not successful.\n const status = response.status.toString()\n if (status in responses\n && typeof responses[status] === 'object'\n && responses[status] !== null\n && 'description' in responses[status]\n && typeof responses[status].description === 'string')\n throw new Error(responses[status].description)\n\n // --- Throw a generic error if the response was not successful.\n throw new Error(response.statusText)\n }\n },\n }) as Service<T>\n}\n"],"names":["getServerUrl","resolveOperation","fetch","handleResponse"],"mappings":";;;AAuCgB,SAAA,cAAgC,UAAuB,gBAAgD;AAC9G,SAAA,IAAI,MAAM,IAAI;AAAA,IACnB,IAAI,GAAG,IAAoB;AAClB,aAAA,OAAM,MAAc,YAA4B;AAGrD,cAAM,UAAUA,iBAAAA,aAAa,QAAQ,GAC/B,YAAYC,iBAAAA,iBAAiB,UAAU,EAAE,GAGzC,EAAE,QAAQ,MAAM,YAAY,GAAG,IAAI,WACnC,WAAW,MAAMC,eAAAA,MAAM,MAAM,EAAE,QAAQ,SAAS,MAAM,GAAG,gBAAgB,GAAG,SAAS;AACvF,YAAA,SAAS,GAAI,QAAOC,eAAe,eAAA,UAAU,EAAE,GAAG,gBAAgB,GAAG,SAAS;AAG5E,cAAA,SAAS,SAAS,OAAO,SAAS;AACxC,cAAI,UAAU,aACT,OAAO,UAAU,MAAM,KAAM,YAC7B,UAAU,MAAM,MAAM,QACtB,iBAAiB,UAAU,MAAM,KACjC,OAAO,UAAU,MAAM,EAAE,eAAgB,WACtC,IAAI,MAAM,UAAU,MAAM,EAAE,WAAW,IAGzC,IAAI,MAAM,SAAS,UAAU;AAAA,MACrC;AAAA,IAAA;AAAA,EACF,CACD;AACH;;"}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { MaybeLiteral } from '@unshared/types';
|
2
|
+
import { b as OperationId, d as OperationById, e as OperationOptions, f as OperationResult, S as ServerUrl, a as OpenAPIV3 } from './chunks/CjU0376e.js';
|
3
|
+
import { c as RequestOptions } from './chunks/B92aAMq0.js';
|
4
|
+
import 'openapi-types';
|
5
|
+
import './HttpHeaders.js';
|
6
|
+
import './HttpMethods.js';
|
7
|
+
|
8
|
+
/** A service instance for the given OpenAPI specification. */
|
9
|
+
type Service<T> = {
|
10
|
+
[K in OperationId<T>]: OperationById<T, K> extends infer U extends OperationById<T, K> ? (data: OperationOptions<T, U>['data'], options?: OperationOptions<T, U>) => Promise<OperationResult<T, U>> : never;
|
11
|
+
};
|
12
|
+
/** The options to pass to the service client. */
|
13
|
+
interface ServiceOptions<T = any> extends RequestOptions {
|
14
|
+
baseUrl?: MaybeLiteral<ServerUrl<T>>;
|
15
|
+
headers?: T extends {
|
16
|
+
openapi: string;
|
17
|
+
} ? OpenAPIV3.ServerHeaders<T> : never;
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* Create a new client instance for the given OpenAPI specification.
|
21
|
+
*
|
22
|
+
* @param document The OpenAPI specification document.
|
23
|
+
* @param initialOptions The initial options to use for every request.
|
24
|
+
* @returns The client instance.
|
25
|
+
* @example
|
26
|
+
*
|
27
|
+
* // Import the Giphy OpenAPI specification.
|
28
|
+
* import Giphy from './giphy.openapi.json'
|
29
|
+
*
|
30
|
+
* // Create a new service instance for the Giphy API.
|
31
|
+
* const service = createService(Giphy, { headers: { 'Bearer' } })
|
32
|
+
*
|
33
|
+
* // Request the "searchGifs" operation from the Giphy API.
|
34
|
+
* await service.getGifs({ limit: 10, offset: 0, q: 'cats' }) // => { data: [...] }
|
35
|
+
*/
|
36
|
+
declare function createService<T extends object>(document: Readonly<T>, initialOptions?: ServiceOptions<T>): Service<T>;
|
37
|
+
|
38
|
+
export { type Service, type ServiceOptions, createService };
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { g as getServerUrl, r as resolveOperation } from "./chunks/Biic1J5b.js";
|
2
|
+
import { f as fetch, h as handleResponse } from "./chunks/D51s1VII.js";
|
3
|
+
import "@unshared/functions/awaitable";
|
4
|
+
function createService(document, initialOptions) {
|
5
|
+
return new Proxy({}, {
|
6
|
+
get(_, id) {
|
7
|
+
return async (data, options) => {
|
8
|
+
const baseUrl = getServerUrl(document), operation = resolveOperation(document, id), { method, path, responses = {} } = operation, response = await fetch(path, { method, baseUrl, data, ...initialOptions, ...options });
|
9
|
+
if (response.ok) return handleResponse(response, { ...initialOptions, ...options });
|
10
|
+
const status = response.status.toString();
|
11
|
+
throw status in responses && typeof responses[status] == "object" && responses[status] !== null && "description" in responses[status] && typeof responses[status].description == "string" ? new Error(responses[status].description) : new Error(response.statusText);
|
12
|
+
};
|
13
|
+
}
|
14
|
+
});
|
15
|
+
}
|
16
|
+
export {
|
17
|
+
createService
|
18
|
+
};
|
19
|
+
//# sourceMappingURL=createService.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createService.js","sources":["../createService.ts"],"sourcesContent":["import type { MaybeLiteral } from '@unshared/types'\nimport type { OpenAPIV3, Operation, OperationById, OperationId, OperationOptions, OperationResult, ServerUrl } from './openapi'\nimport type { RequestOptions } from './utils/request'\nimport { getServerUrl } from './openapi/getServerUrl'\nimport { resolveOperation } from './openapi/resolveOperation'\nimport { fetch } from './utils/fetch'\nimport { handleResponse } from './utils/handleResponse'\n\n/** A service instance for the given OpenAPI specification. */\nexport type Service<T> = {\n [K in OperationId<T>]:\n OperationById<T, K> extends infer U extends OperationById<T, K>\n ? (data: OperationOptions<T, U>['data'], options?: OperationOptions<T, U>) => Promise<OperationResult<T, U>>\n : never\n}\n\n/** The options to pass to the service client. */\nexport interface ServiceOptions<T = any> extends RequestOptions {\n baseUrl?: MaybeLiteral<ServerUrl<T>>\n headers?: T extends { openapi: string } ? OpenAPIV3.ServerHeaders<T> : never\n}\n\n/**\n * Create a new client instance for the given OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param initialOptions The initial options to use for every request.\n * @returns The client instance.\n * @example\n *\n * // Import the Giphy OpenAPI specification.\n * import Giphy from './giphy.openapi.json'\n *\n * // Create a new service instance for the Giphy API.\n * const service = createService(Giphy, { headers: { 'Bearer' } })\n *\n * // Request the \"searchGifs\" operation from the Giphy API.\n * await service.getGifs({ limit: 10, offset: 0, q: 'cats' }) // => { data: [...] }\n */\nexport function createService<T extends object>(document: Readonly<T>, initialOptions?: ServiceOptions<T>): Service<T> {\n return new Proxy({}, {\n get(_, id: OperationId<T>) {\n return async(data: object, options: RequestOptions) => {\n\n // --- Find the operation in the OpenAPI specification.\n const baseUrl = getServerUrl(document)\n const operation = resolveOperation(document, id) as Operation\n\n // --- Fetch the relevant resource from the server.\n const { method, path, responses = {} } = operation\n const response = await fetch(path, { method, baseUrl, data, ...initialOptions, ...options })\n if (response.ok) return handleResponse(response, { ...initialOptions, ...options })\n\n // --- Throw an error if the response was not successful.\n const status = response.status.toString()\n if (status in responses\n && typeof responses[status] === 'object'\n && responses[status] !== null\n && 'description' in responses[status]\n && typeof responses[status].description === 'string')\n throw new Error(responses[status].description)\n\n // --- Throw a generic error if the response was not successful.\n throw new Error(response.statusText)\n }\n },\n }) as Service<T>\n}\n"],"names":[],"mappings":";;;AAuCgB,SAAA,cAAgC,UAAuB,gBAAgD;AAC9G,SAAA,IAAI,MAAM,IAAI;AAAA,IACnB,IAAI,GAAG,IAAoB;AAClB,aAAA,OAAM,MAAc,YAA4B;AAGrD,cAAM,UAAU,aAAa,QAAQ,GAC/B,YAAY,iBAAiB,UAAU,EAAE,GAGzC,EAAE,QAAQ,MAAM,YAAY,GAAG,IAAI,WACnC,WAAW,MAAM,MAAM,MAAM,EAAE,QAAQ,SAAS,MAAM,GAAG,gBAAgB,GAAG,SAAS;AACvF,YAAA,SAAS,GAAI,QAAO,eAAe,UAAU,EAAE,GAAG,gBAAgB,GAAG,SAAS;AAG5E,cAAA,SAAS,SAAS,OAAO,SAAS;AACxC,cAAI,UAAU,aACT,OAAO,UAAU,MAAM,KAAM,YAC7B,UAAU,MAAM,MAAM,QACtB,iBAAiB,UAAU,MAAM,KACjC,OAAO,UAAU,MAAM,EAAE,eAAgB,WACtC,IAAI,MAAM,UAAU,MAAM,EAAE,WAAW,IAGzC,IAAI,MAAM,SAAS,UAAU;AAAA,MACrC;AAAA,IAAA;AAAA,EACF,CACD;AACH;"}
|