@nestia/fetcher 10.0.2 → 11.0.0-dev.20260305

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -93
  3. package/package.json +20 -13
  4. package/src/AesPkcs5.ts +41 -49
  5. package/src/EncryptedFetcher.ts +176 -176
  6. package/src/FormDataInput.ts +80 -80
  7. package/src/HttpError.ts +1 -1
  8. package/src/IConnection.ts +241 -241
  9. package/src/IEncryptionPassword.ts +44 -44
  10. package/src/IFetchEvent.ts +31 -31
  11. package/src/IFetchRoute.ts +60 -60
  12. package/src/IPropagation.ts +99 -99
  13. package/src/NestiaSimulator.ts +82 -82
  14. package/src/PlainFetcher.ts +105 -105
  15. package/src/index.ts +12 -7
  16. package/src/internal/FetcherBase.ts +235 -235
  17. package/lib/AesPkcs5.d.ts +0 -30
  18. package/lib/AesPkcs5.js +0 -49
  19. package/lib/AesPkcs5.js.map +0 -1
  20. package/lib/EncryptedFetcher.d.ts +0 -47
  21. package/lib/EncryptedFetcher.js +0 -139
  22. package/lib/EncryptedFetcher.js.map +0 -1
  23. package/lib/FormDataInput.d.ts +0 -70
  24. package/lib/FormDataInput.js +0 -3
  25. package/lib/FormDataInput.js.map +0 -1
  26. package/lib/HttpError.d.ts +0 -1
  27. package/lib/HttpError.js +0 -6
  28. package/lib/HttpError.js.map +0 -1
  29. package/lib/IConnection.d.ts +0 -165
  30. package/lib/IConnection.js +0 -3
  31. package/lib/IConnection.js.map +0 -1
  32. package/lib/IEncryptionPassword.d.ts +0 -41
  33. package/lib/IEncryptionPassword.js +0 -3
  34. package/lib/IEncryptionPassword.js.map +0 -1
  35. package/lib/IFetchEvent.d.ts +0 -11
  36. package/lib/IFetchEvent.js +0 -21
  37. package/lib/IFetchEvent.js.map +0 -1
  38. package/lib/IFetchRoute.d.ts +0 -46
  39. package/lib/IFetchRoute.js +0 -3
  40. package/lib/IFetchRoute.js.map +0 -1
  41. package/lib/IPropagation.d.ts +0 -69
  42. package/lib/IPropagation.js +0 -3
  43. package/lib/IPropagation.js.map +0 -1
  44. package/lib/MigrateFetcher.d.ts +0 -19
  45. package/lib/MigrateFetcher.js +0 -179
  46. package/lib/MigrateFetcher.js.map +0 -1
  47. package/lib/NestiaSimulator.d.ts +0 -13
  48. package/lib/NestiaSimulator.js +0 -62
  49. package/lib/NestiaSimulator.js.map +0 -1
  50. package/lib/PlainFetcher.d.ts +0 -46
  51. package/lib/PlainFetcher.js +0 -89
  52. package/lib/PlainFetcher.js.map +0 -1
  53. package/lib/index.d.ts +0 -7
  54. package/lib/index.js +0 -24
  55. package/lib/index.js.map +0 -1
  56. package/lib/internal/FetcherBase.d.ts +0 -1
  57. package/lib/internal/FetcherBase.js +0 -348
  58. package/lib/internal/FetcherBase.js.map +0 -1
  59. package/src/MigrateFetcher.ts +0 -118
@@ -1,176 +1,176 @@
1
- import { AesPkcs5 } from "./AesPkcs5";
2
- import { IConnection } from "./IConnection";
3
- import { IEncryptionPassword } from "./IEncryptionPassword";
4
- import { IFetchRoute } from "./IFetchRoute";
5
- import { IPropagation } from "./IPropagation";
6
- import { FetcherBase } from "./internal/FetcherBase";
7
-
8
- /**
9
- * Utility class for `fetch` functions used in `@nestia/sdk` with encryption.
10
- *
11
- * `EncryptedFetcher` is a utility class designed for SDK functions generated by
12
- * [`@nestia/sdk`](https://nestia.io/docs/sdk/sdk), interacting with the remote
13
- * HTTP API encrypted by AES-PKCS algorithm. In other words, this is a
14
- * collection of dedicated `fetch()` functions for `@nestia/sdk` with
15
- * encryption.
16
- *
17
- * For reference, `EncryptedFetcher` class being used only when target
18
- * controller method is encrypting body data by `@EncryptedRoute` or
19
- * `@EncryptedBody` decorators. If those decorators are not used,
20
- * {@link PlainFetcher} class would be used instead.
21
- *
22
- * @author Jeongho Nam - https://github.com/samchon
23
- */
24
- export namespace EncryptedFetcher {
25
- /**
26
- * Fetch function only for `HEAD` method.
27
- *
28
- * @param connection Connection information for the remote HTTP server
29
- * @param route Route information about the target API
30
- * @returns Nothing because of `HEAD` method
31
- */
32
- export function fetch(
33
- connection: IConnection,
34
- route: IFetchRoute<"HEAD">,
35
- ): Promise<void>;
36
-
37
- /**
38
- * Fetch function only for `GET` method.
39
- *
40
- * @param connection Connection information for the remote HTTP server
41
- * @param route Route information about the target API
42
- * @returns Response body data from the remote API
43
- */
44
- export function fetch<Output>(
45
- connection: IConnection,
46
- route: IFetchRoute<"GET">,
47
- ): Promise<Output>;
48
-
49
- /**
50
- * Fetch function for the `POST`, `PUT`, `PATCH` and `DELETE` methods.
51
- *
52
- * @param connection Connection information for the remote HTTP server
53
- * @param route Route information about the target API
54
- * @returns Response body data from the remote API
55
- */
56
- export function fetch<Input, Output>(
57
- connection: IConnection,
58
- route: IFetchRoute<"POST" | "PUT" | "PATCH" | "DELETE">,
59
- input?: Input,
60
- stringify?: (input: Input) => string,
61
- ): Promise<Output>;
62
-
63
- export async function fetch<Input, Output>(
64
- connection: IConnection,
65
- route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
66
- input?: Input,
67
- stringify?: (input: Input) => string,
68
- ): Promise<Output> {
69
- if (
70
- (route.request?.encrypted === true || route.response?.encrypted) &&
71
- connection.encryption === undefined
72
- )
73
- throw new Error(
74
- "Error on EncryptedFetcher.fetch(): the encryption password has not been configured.",
75
- );
76
- const closure =
77
- typeof connection.encryption === "function"
78
- ? (direction: "encode" | "decode") =>
79
- (
80
- headers: Record<string, IConnection.HeaderValue | undefined>,
81
- body: string,
82
- ) =>
83
- (connection.encryption as IEncryptionPassword.Closure)({
84
- headers,
85
- body,
86
- direction,
87
- })
88
- : () => () => connection.encryption as IEncryptionPassword;
89
-
90
- return FetcherBase.request({
91
- className: "EncryptedFetcher",
92
- encode:
93
- route.request?.encrypted === true
94
- ? (input, headers) => {
95
- const p: IEncryptionPassword = closure("encode")(headers, input);
96
- return AesPkcs5.encrypt(
97
- (stringify ?? JSON.stringify)(input),
98
- p.key,
99
- p.iv,
100
- );
101
- }
102
- : (input) => input,
103
- decode:
104
- route.response?.encrypted === true
105
- ? (input, headers) => {
106
- const p: IEncryptionPassword = closure("decode")(headers, input);
107
- const s: string = AesPkcs5.decrypt(input, p.key, p.iv);
108
- return s.length ? JSON.parse(s) : s;
109
- }
110
- : (input) => input,
111
- })(connection, route, input, stringify);
112
- }
113
-
114
- export function propagate<Output extends IPropagation<any, any>>(
115
- connection: IConnection,
116
- route: IFetchRoute<"GET" | "HEAD">,
117
- ): Promise<Output>;
118
-
119
- export function propagate<Input, Output extends IPropagation<any, any>>(
120
- connection: IConnection,
121
- route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
122
- input?: Input,
123
- stringify?: (input: Input) => string,
124
- ): Promise<Output>;
125
-
126
- export async function propagate<Input, Output extends IPropagation<any, any>>(
127
- connection: IConnection,
128
- route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
129
- input?: Input,
130
- stringify?: (input: Input) => string,
131
- ): Promise<Output> {
132
- if (
133
- (route.request?.encrypted === true || route.response?.encrypted) &&
134
- connection.encryption === undefined
135
- )
136
- throw new Error(
137
- "Error on EncryptedFetcher.propagate(): the encryption password has not been configured.",
138
- );
139
- const closure =
140
- typeof connection.encryption === "function"
141
- ? (direction: "encode" | "decode") =>
142
- (
143
- headers: Record<string, IConnection.HeaderValue | undefined>,
144
- body: string,
145
- ) =>
146
- (connection.encryption as IEncryptionPassword.Closure)({
147
- headers,
148
- body,
149
- direction,
150
- })
151
- : () => () => connection.encryption as IEncryptionPassword;
152
-
153
- return FetcherBase.propagate({
154
- className: "EncryptedFetcher",
155
- encode:
156
- route.request?.encrypted === true
157
- ? (input, headers) => {
158
- const p: IEncryptionPassword = closure("encode")(headers, input);
159
- return AesPkcs5.encrypt(
160
- (stringify ?? JSON.stringify)(input),
161
- p.key,
162
- p.iv,
163
- );
164
- }
165
- : (input) => input,
166
- decode:
167
- route.response?.encrypted === true
168
- ? (input, headers) => {
169
- const p: IEncryptionPassword = closure("decode")(headers, input);
170
- const s: string = AesPkcs5.decrypt(input, p.key, p.iv);
171
- return s.length ? JSON.parse(s) : s;
172
- }
173
- : (input) => input,
174
- })(connection, route, input, stringify) as Promise<Output>;
175
- }
176
- }
1
+ import { AesPkcs5 } from "./AesPkcs5";
2
+ import { IConnection } from "./IConnection";
3
+ import { IEncryptionPassword } from "./IEncryptionPassword";
4
+ import { IFetchRoute } from "./IFetchRoute";
5
+ import { IPropagation } from "./IPropagation";
6
+ import { FetcherBase } from "./internal/FetcherBase";
7
+
8
+ /**
9
+ * Utility class for `fetch` functions used in `@nestia/sdk` with encryption.
10
+ *
11
+ * `EncryptedFetcher` is a utility class designed for SDK functions generated by
12
+ * [`@nestia/sdk`](https://nestia.io/docs/sdk/sdk), interacting with the remote
13
+ * HTTP API encrypted by AES-PKCS algorithm. In other words, this is a
14
+ * collection of dedicated `fetch()` functions for `@nestia/sdk` with
15
+ * encryption.
16
+ *
17
+ * For reference, `EncryptedFetcher` class being used only when target
18
+ * controller method is encrypting body data by `@EncryptedRoute` or
19
+ * `@EncryptedBody` decorators. If those decorators are not used,
20
+ * {@link PlainFetcher} class would be used instead.
21
+ *
22
+ * @author Jeongho Nam - https://github.com/samchon
23
+ */
24
+ export namespace EncryptedFetcher {
25
+ /**
26
+ * Fetch function only for `HEAD` method.
27
+ *
28
+ * @param connection Connection information for the remote HTTP server
29
+ * @param route Route information about the target API
30
+ * @returns Nothing because of `HEAD` method
31
+ */
32
+ export function fetch(
33
+ connection: IConnection,
34
+ route: IFetchRoute<"HEAD">,
35
+ ): Promise<void>;
36
+
37
+ /**
38
+ * Fetch function only for `GET` method.
39
+ *
40
+ * @param connection Connection information for the remote HTTP server
41
+ * @param route Route information about the target API
42
+ * @returns Response body data from the remote API
43
+ */
44
+ export function fetch<Output>(
45
+ connection: IConnection,
46
+ route: IFetchRoute<"GET">,
47
+ ): Promise<Output>;
48
+
49
+ /**
50
+ * Fetch function for the `POST`, `PUT`, `PATCH` and `DELETE` methods.
51
+ *
52
+ * @param connection Connection information for the remote HTTP server
53
+ * @param route Route information about the target API
54
+ * @returns Response body data from the remote API
55
+ */
56
+ export function fetch<Input, Output>(
57
+ connection: IConnection,
58
+ route: IFetchRoute<"POST" | "PUT" | "PATCH" | "DELETE">,
59
+ input?: Input,
60
+ stringify?: (input: Input) => string,
61
+ ): Promise<Output>;
62
+
63
+ export async function fetch<Input, Output>(
64
+ connection: IConnection,
65
+ route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
66
+ input?: Input,
67
+ stringify?: (input: Input) => string,
68
+ ): Promise<Output> {
69
+ if (
70
+ (route.request?.encrypted === true || route.response?.encrypted) &&
71
+ connection.encryption === undefined
72
+ )
73
+ throw new Error(
74
+ "Error on EncryptedFetcher.fetch(): the encryption password has not been configured.",
75
+ );
76
+ const closure =
77
+ typeof connection.encryption === "function"
78
+ ? (direction: "encode" | "decode") =>
79
+ (
80
+ headers: Record<string, IConnection.HeaderValue | undefined>,
81
+ body: string,
82
+ ) =>
83
+ (connection.encryption as IEncryptionPassword.Closure)({
84
+ headers,
85
+ body,
86
+ direction,
87
+ })
88
+ : () => () => connection.encryption as IEncryptionPassword;
89
+
90
+ return FetcherBase.request({
91
+ className: "EncryptedFetcher",
92
+ encode:
93
+ route.request?.encrypted === true
94
+ ? (input, headers) => {
95
+ const p: IEncryptionPassword = closure("encode")(headers, input);
96
+ return AesPkcs5.encrypt(
97
+ (stringify ?? JSON.stringify)(input),
98
+ p.key,
99
+ p.iv,
100
+ );
101
+ }
102
+ : (input) => input,
103
+ decode:
104
+ route.response?.encrypted === true
105
+ ? (input, headers) => {
106
+ const p: IEncryptionPassword = closure("decode")(headers, input);
107
+ const s: string = AesPkcs5.decrypt(input, p.key, p.iv);
108
+ return s.length ? JSON.parse(s) : s;
109
+ }
110
+ : (input) => input,
111
+ })(connection, route, input, stringify);
112
+ }
113
+
114
+ export function propagate<Output extends IPropagation<any, any>>(
115
+ connection: IConnection,
116
+ route: IFetchRoute<"GET" | "HEAD">,
117
+ ): Promise<Output>;
118
+
119
+ export function propagate<Input, Output extends IPropagation<any, any>>(
120
+ connection: IConnection,
121
+ route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
122
+ input?: Input,
123
+ stringify?: (input: Input) => string,
124
+ ): Promise<Output>;
125
+
126
+ export async function propagate<Input, Output extends IPropagation<any, any>>(
127
+ connection: IConnection,
128
+ route: IFetchRoute<"DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT">,
129
+ input?: Input,
130
+ stringify?: (input: Input) => string,
131
+ ): Promise<Output> {
132
+ if (
133
+ (route.request?.encrypted === true || route.response?.encrypted) &&
134
+ connection.encryption === undefined
135
+ )
136
+ throw new Error(
137
+ "Error on EncryptedFetcher.propagate(): the encryption password has not been configured.",
138
+ );
139
+ const closure =
140
+ typeof connection.encryption === "function"
141
+ ? (direction: "encode" | "decode") =>
142
+ (
143
+ headers: Record<string, IConnection.HeaderValue | undefined>,
144
+ body: string,
145
+ ) =>
146
+ (connection.encryption as IEncryptionPassword.Closure)({
147
+ headers,
148
+ body,
149
+ direction,
150
+ })
151
+ : () => () => connection.encryption as IEncryptionPassword;
152
+
153
+ return FetcherBase.propagate({
154
+ className: "EncryptedFetcher",
155
+ encode:
156
+ route.request?.encrypted === true
157
+ ? (input, headers) => {
158
+ const p: IEncryptionPassword = closure("encode")(headers, input);
159
+ return AesPkcs5.encrypt(
160
+ (stringify ?? JSON.stringify)(input),
161
+ p.key,
162
+ p.iv,
163
+ );
164
+ }
165
+ : (input) => input,
166
+ decode:
167
+ route.response?.encrypted === true
168
+ ? (input, headers) => {
169
+ const p: IEncryptionPassword = closure("decode")(headers, input);
170
+ const s: string = AesPkcs5.decrypt(input, p.key, p.iv);
171
+ return s.length ? JSON.parse(s) : s;
172
+ }
173
+ : (input) => input,
174
+ })(connection, route, input, stringify) as Promise<Output>;
175
+ }
176
+ }
@@ -1,80 +1,80 @@
1
- /**
2
- * FormData input type.
3
- *
4
- * `FormDataInput<T>` is a type for the input of the `FormData` request, casting
5
- * `File` property value type as an union of `File` and
6
- * {@link FormDataInput.IFileProps}, especially for the React Native
7
- * environment.
8
- *
9
- * You know what? In the React Native environment, `File` class is not
10
- * supported. Therefore, when composing a `FormData` request, you have to put
11
- * the URI address of the local filesystem with file name and content type that
12
- * is represented by the {@link FormDataInput.IFileProps} type.
13
- *
14
- * This `FormDataInput<T>` type is designed for that purpose. If the property
15
- * value type is a `File` class, it converts it to an union type of `File` and
16
- * {@link FormDataInput.IFileProps} type. Also, if the property value type is an
17
- * array of `File` class, it converts it to an array of union type of `File` and
18
- * {@link FormDataInput.IFileProps} type too.
19
- *
20
- * Before | After ----------|------------------------ `boolean` | `boolean`
21
- * `bigint` | `bigint` `number` | `number` `string` | `string` `File` | `File \|
22
- * IFileProps`
23
- *
24
- * @author Jeongho Nam - https://github.com/samchon
25
- * @template T Target object type.
26
- */
27
- export type FormDataInput<T extends object> =
28
- T extends Array<any>
29
- ? never
30
- : T extends Function
31
- ? never
32
- : {
33
- [P in keyof T]: T[P] extends Array<infer U>
34
- ? FormDataInput.Value<U>[]
35
- : FormDataInput.Value<T[P]>;
36
- };
37
- export namespace FormDataInput {
38
- /**
39
- * Value type of the `FormDataInput`.
40
- *
41
- * `Value<T>` is a type for the property value defined in the `FormDataInput`.
42
- *
43
- * If the original value type is a `File` class, `Value<T>` converts it to an
44
- * union type of `File` and {@link IFileProps} type which is a structured data
45
- * for the URI file location in the React Native environment.
46
- */
47
- export type Value<T> = T extends File ? T | IFileProps : T;
48
-
49
- /**
50
- * Properties of a file.
51
- *
52
- * In the React Native, this `IFileProps` structured data can replace the
53
- * `File` class instance in the `FormData` request.
54
- *
55
- * Just put the {@link uri URI address} of the local file system with the
56
- * file's {@link name} and {@link type}. It would be casted to the `File` class
57
- * instance automatically in the `FormData` request.
58
- *
59
- * Note that, this `IFileProps` type works only in the React Native
60
- * environment. If you are developing a Web or NodeJS application, you have to
61
- * utilize the `File` class instance directly.
62
- */
63
- export interface IFileProps {
64
- /**
65
- * URI address of the file.
66
- *
67
- * In the React Native, the URI address in the local file system can replace
68
- * the `File` class instance. If
69
- *
70
- * @format uri
71
- */
72
- uri: string;
73
-
74
- /** Name of the file. */
75
- name: string;
76
-
77
- /** Content type of the file. */
78
- type: string;
79
- }
80
- }
1
+ /**
2
+ * FormData input type.
3
+ *
4
+ * `FormDataInput<T>` is a type for the input of the `FormData` request, casting
5
+ * `File` property value type as an union of `File` and
6
+ * {@link FormDataInput.IFileProps}, especially for the React Native
7
+ * environment.
8
+ *
9
+ * You know what? In the React Native environment, `File` class is not
10
+ * supported. Therefore, when composing a `FormData` request, you have to put
11
+ * the URI address of the local filesystem with file name and content type that
12
+ * is represented by the {@link FormDataInput.IFileProps} type.
13
+ *
14
+ * This `FormDataInput<T>` type is designed for that purpose. If the property
15
+ * value type is a `File` class, it converts it to an union type of `File` and
16
+ * {@link FormDataInput.IFileProps} type. Also, if the property value type is an
17
+ * array of `File` class, it converts it to an array of union type of `File` and
18
+ * {@link FormDataInput.IFileProps} type too.
19
+ *
20
+ * Before | After ----------|------------------------ `boolean` | `boolean`
21
+ * `bigint` | `bigint` `number` | `number` `string` | `string` `File` | `File \|
22
+ * IFileProps`
23
+ *
24
+ * @author Jeongho Nam - https://github.com/samchon
25
+ * @template T Target object type.
26
+ */
27
+ export type FormDataInput<T extends object> =
28
+ T extends Array<any>
29
+ ? never
30
+ : T extends Function
31
+ ? never
32
+ : {
33
+ [P in keyof T]: T[P] extends Array<infer U>
34
+ ? FormDataInput.Value<U>[]
35
+ : FormDataInput.Value<T[P]>;
36
+ };
37
+ export namespace FormDataInput {
38
+ /**
39
+ * Value type of the `FormDataInput`.
40
+ *
41
+ * `Value<T>` is a type for the property value defined in the `FormDataInput`.
42
+ *
43
+ * If the original value type is a `File` class, `Value<T>` converts it to an
44
+ * union type of `File` and {@link IFileProps} type which is a structured data
45
+ * for the URI file location in the React Native environment.
46
+ */
47
+ export type Value<T> = T extends File ? T | IFileProps : T;
48
+
49
+ /**
50
+ * Properties of a file.
51
+ *
52
+ * In the React Native, this `IFileProps` structured data can replace the
53
+ * `File` class instance in the `FormData` request.
54
+ *
55
+ * Just put the {@link uri URI address} of the local file system with the
56
+ * file's {@link name} and {@link type}. It would be casted to the `File` class
57
+ * instance automatically in the `FormData` request.
58
+ *
59
+ * Note that, this `IFileProps` type works only in the React Native
60
+ * environment. If you are developing a Web or NodeJS application, you have to
61
+ * utilize the `File` class instance directly.
62
+ */
63
+ export interface IFileProps {
64
+ /**
65
+ * URI address of the file.
66
+ *
67
+ * In the React Native, the URI address in the local file system can replace
68
+ * the `File` class instance. If
69
+ *
70
+ * @format uri
71
+ */
72
+ uri: string;
73
+
74
+ /** Name of the file. */
75
+ name: string;
76
+
77
+ /** Content type of the file. */
78
+ type: string;
79
+ }
80
+ }
package/src/HttpError.ts CHANGED
@@ -1 +1 @@
1
- export { HttpError } from "@samchon/openapi";
1
+ export { HttpError } from "@typia/utils";