@intrig/react 0.0.7 → 0.0.8

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.
@@ -0,0 +1,198 @@
1
+ import { ZodSchema } from 'zod';
2
+ import { XMLParser } from 'fast-xml-parser';
3
+
4
+ // type Encoders = {
5
+ // [k: string]: <T>(
6
+ // request: T,
7
+ // mediaType: string,
8
+ // schema: ZodSchema,
9
+ // ) => Promise<any>;
10
+ // };
11
+
12
+ type EncodersSync = {
13
+ [k: string]: <T>(request: T, mediaType: string, schema: ZodSchema) => any;
14
+ };
15
+
16
+ const encoders: EncodersSync = {};
17
+
18
+ export function encode<T>(request: T, mediaType: string, schema: ZodSchema) {
19
+ if (encoders[mediaType]) {
20
+ return encoders[mediaType](request, mediaType, schema);
21
+ }
22
+ return request;
23
+ }
24
+
25
+ encoders['application/json'] = (request, mediaType, schema) => {
26
+ return request;
27
+ };
28
+
29
+ function appendFormData(
30
+ formData: FormData,
31
+ data: any,
32
+ parentKey: string,
33
+ ): void {
34
+ if (data instanceof Blob || typeof data === 'string') {
35
+ formData.append(parentKey, data);
36
+ } else if (data !== null && typeof data === 'object') {
37
+ if (Array.isArray(data)) {
38
+ data.forEach((item: any, index: number) => {
39
+ const key = `${parentKey}`;
40
+ appendFormData(formData, item, key);
41
+ });
42
+ } else {
43
+ Object.keys(data).forEach((key: string) => {
44
+ const newKey = parentKey ? `${parentKey}[${key}]` : key;
45
+ appendFormData(formData, data[key], newKey);
46
+ });
47
+ }
48
+ } else {
49
+ formData.append(parentKey, data == null ? '' : String(data));
50
+ }
51
+ }
52
+
53
+ encoders['multipart/form-data'] = (request, mediaType, schema) => {
54
+ const _request = request as Record<string, any>;
55
+ const formData = new FormData();
56
+ Object.keys(_request).forEach((key: string) => {
57
+ appendFormData(formData, _request[key], key);
58
+ });
59
+ return formData;
60
+ };
61
+
62
+ encoders['application/octet-stream'] = (request, mediaType, schema) => {
63
+ return request;
64
+ };
65
+
66
+ encoders['application/x-www-form-urlencoded'] = (
67
+ request,
68
+ mediaType,
69
+ schema,
70
+ ) => {
71
+ const formData = new FormData();
72
+ for (const key in request) {
73
+ const value = request[key];
74
+ formData.append(
75
+ key,
76
+ value instanceof Blob || typeof value === 'string'
77
+ ? value
78
+ : String(value),
79
+ );
80
+ }
81
+ return formData;
82
+ };
83
+
84
+ type Transformers = {
85
+ [k: string]: <T>(
86
+ request: Request,
87
+ mediaType: string,
88
+ schema: ZodSchema,
89
+ ) => Promise<T>;
90
+ };
91
+
92
+ const transformers: Transformers = {};
93
+
94
+ export function transform<T>(
95
+ request: Request,
96
+ mediaType: string,
97
+ schema: ZodSchema,
98
+ ): Promise<T> {
99
+ if (transformers[mediaType]) {
100
+ return transformers[mediaType](request, mediaType, schema);
101
+ }
102
+ throw new Error(`Unsupported media type: ` + mediaType);
103
+ }
104
+
105
+ transformers['application/json'] = async (request, mediaType, schema) => {
106
+ return schema.parse(await request.json());
107
+ };
108
+
109
+ transformers['multipart/form-data'] = async (request, mediaType, schema) => {
110
+ const formData = await request.formData();
111
+ const content: Record<string, any> = {};
112
+ formData.forEach((value, key) => {
113
+ if (content[key]) {
114
+ if (!(content[key] instanceof Array)) {
115
+ content[key] = [content[key]];
116
+ }
117
+ content[key].push(value);
118
+ } else {
119
+ content[key] = value;
120
+ }
121
+ });
122
+ return schema.parse(content);
123
+ };
124
+
125
+ transformers['application/octet-stream'] = async (
126
+ request,
127
+ mediaType,
128
+ schema,
129
+ ) => {
130
+ return schema.parse(
131
+ new Blob([await request.arrayBuffer()], {
132
+ type: 'application/octet-stream',
133
+ }),
134
+ );
135
+ };
136
+
137
+ transformers['application/x-www-form-urlencoded'] = async (
138
+ request,
139
+ mediaType,
140
+ schema,
141
+ ) => {
142
+ const formData = await request.formData();
143
+ const content: Record<string, any> = {};
144
+ formData.forEach((value, key) => (content[key] = value));
145
+ return schema.parse(content);
146
+ };
147
+
148
+ transformers['application/xml'] = async (request, mediaType, schema) => {
149
+ const xmlParser = new XMLParser();
150
+ const content = await xmlParser.parse(await request.text());
151
+ return schema.parse(await content);
152
+ };
153
+
154
+ transformers['text/plain'] = async (request, mediaType, schema) => {
155
+ return schema.parse(await request.text());
156
+ };
157
+
158
+ transformers['text/html'] = async (request, mediaType, schema) => {
159
+ return schema.parse(await request.text());
160
+ };
161
+
162
+ transformers['text/css'] = async (request, mediaType, schema) => {
163
+ return schema.parse(await request.text());
164
+ };
165
+
166
+ transformers['text/javascript'] = async (request, mediaType, schema) => {
167
+ return schema.parse(await request.text());
168
+ };
169
+
170
+ type ResponseTransformers = {
171
+ [k: string]: <T>(
172
+ data: any,
173
+ mediaType: string,
174
+ schema: ZodSchema,
175
+ ) => Promise<T>;
176
+ };
177
+
178
+ const responseTransformers: ResponseTransformers = {};
179
+
180
+ responseTransformers['application/json'] = async (data, mediaType, schema) => {
181
+ return schema.parse(data);
182
+ };
183
+
184
+ responseTransformers['application/xml'] = async (data, mediaType, schema) => {
185
+ const parsed = new XMLParser().parse(data);
186
+ return schema.parse(parsed);
187
+ };
188
+
189
+ export async function transformResponse<T>(
190
+ data: any,
191
+ mediaType: string,
192
+ schema: ZodSchema,
193
+ ): Promise<T> {
194
+ if (responseTransformers[mediaType]) {
195
+ return await responseTransformers[mediaType](data, mediaType, schema);
196
+ }
197
+ return data;
198
+ }